繁体   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