簡體   English   中英

使用 sem_t 時大小為 8 的無效寫入

[英]invalid write of size 8 when using sem_t

最初,當我在結構中只有一個 sem_t *queue 時,當我初始化它時,程序運行時沒有任何錯誤和問題。

 #include <semaphore.h>

 typedef struct barrier {
   int count;
   sem_t *queue;
} barrier_t;

void barrier_init ( barrier_t *barrier, int count );

#include "barrier.h"
#include <stdlib.h>

// Initialise barrier here
void barrier_init ( barrier_t *barrier, int count ) 
{

  barrier->count = count;
  barrier->queue = malloc(sizeof(sem_t));
  sem_init(barrier->queue, 0, 0);

 }

但是,當我初始化並使用 Valgrind 運行時,當我在 struct barrier 中有兩個 sem_t 時,它會向我發出信號,表明存在大小為 8 的無效寫入,即使程序正常運行和輸出也是如此。

#include "barrier.h"
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
typedef struct barrier {
  int count;
  sem_t *queue, *mutex;
}  barrier_t;

void barrier_init ( barrier_t *barrier, int count ) 
{
 
  barrier->count = count;
  barrier->queue = malloc(sizeof(sem_t));
  barrier->mutex = malloc(sizeof(sem_t));
  sem_init(barrier->mutex, 0, 1);
  sem_init(barrier->queue, 0, 0);

}
void barrier_wait ( barrier_t *barrier ) 
{   
  sem_wait(barrier->mutex);
  barrier->count--;
  sem_post(barrier->mutex);

  if (barrier->count == 0) {      
    sem_post(barrier->queue);    
  }



  sem_wait(barrier->queue);
  sem_post(barrier->queue);
}

// Perform cleanup here if you need to
void barrier_destroy ( barrier_t *barrier ) 
{

  sem_destroy(barrier->queue);
  sem_destroy(barrier->mutex);
  free(barrier->queue);
  free(barrier->mutex);   
}

主要的 function 是一個模板,應該沒有任何問題。 Valgrind 對 memory 泄漏沒有問題,也只有錯誤指示大小為 8 的無效寫入和讀取。所以這是主要的 function:

#include <pthread.h>
#include <semaphore.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "barrier.h"

sem_t *common_sem;
int waiting_at_barrier = 0;

typedef struct thread_task {
  int       thread_id;
  barrier_t *barrier;
  int       thread_return;
  int       sleep_time;
} thread_task_t;


void* run_thread( void* task ) 
{
  thread_task_t* thread_task = (thread_task_t*) task;
  const int thread_id = thread_task->thread_id;
  barrier_t *barrier = thread_task->barrier;

  usleep( thread_task->sleep_time );

  sem_wait( common_sem );
  waiting_at_barrier++;
  sem_post( common_sem );

  printf ( "[Thread %2d] waiting on barrier\n", thread_id );
  barrier_wait( barrier );
  printf ( "[Thread %2d] exiting barrier\n", thread_id );
  thread_task->thread_return = waiting_at_barrier;

  pthread_exit(0);
  }

int main ( int argc, char *argv[] ) 
{

  if (argc < 2) {
  printf("usage: %s threads [seed]\n", argv[0]);
  exit(1);
  }

  if (argc > 2) {
    srand(atoi(argv[2])); // [atoi] defaults to 0 if cannot be parsed.
  }

  const int total_threads = argc > 1 ? atoi(argv[1]) : 50;
  // initialise common semaphore
  common_sem = malloc(sizeof(sem_t));
  sem_init( common_sem, 0, 1 );


  barrier_t *barrier = malloc( sizeof(barrier_t) );
  barrier_init( barrier, total_threads );

  pthread_t threads[total_threads];
  thread_task_t *thread_tasks = malloc(sizeof(thread_task_t) * 
  total_threads);

  int i;
  for (i = 0; i < total_threads; i++) {
    thread_tasks[i].thread_id = i;
    thread_tasks[i].barrier = barrier;
    thread_tasks[i].sleep_time = (rand() % 500) * 1000;
    pthread_create( &threads[i], NULL, run_thread, (void*) 
    &thread_tasks[i] );
  }

  // wait and collect the tasks
  bool error_found = false;
  for (i = 0; i < total_threads; i++) {
    pthread_join( threads[i], NULL );
    if (thread_tasks[i].thread_return < total_threads) {
    error_found = true;
    printf ( "[Thread %2d] exited with %d other tasks (expected: 
      %d)\n",i,thread_tasks[i].thread_return,
           total_threads );
    }
  }

  free(thread_tasks);

  barrier_destroy(barrier);
  free(barrier);

  sem_destroy( common_sem );
  free( common_sem );

  if (error_found) {
    printf ( "Incorrect executions found\n" );
    exit(1);
  }
  return 0;
  }

這是 Valgrind 錯誤的一部分:

0x1098BB 大小 8 的無效寫入:barrier_init(在 /home/hzxin/work/2106/lab3/L3/ex1/ex1 中)由 0x10948F:main(在 /home/hzxin/work/2106/lab3/L3/ex1/ex1 ) 地址 0x4a730b0 是大小為 16 alloc'dat 0x483B7F3 的塊后的 0 個字節:malloc(在 /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so 中)

我添加了一個小的主 function 和一個簡單的 deinit function。 使用 gcc 9.3.0 編譯並使用 valgrind 3.15 進行檢查沒有問題。 仔細檢查你是如何調用你的函數的。

在 Valgrind 中運行更新后的代碼對我來說效果很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM