valgrind输出:程序停止时free()无效

时间:2016-10-19 21:55:42

标签: c pointers malloc valgrind free

我想实现一个负责并行运行多个任务的应用程序。

在添加实际任务之前,我尝试设置基础,但程序在valgrind执行时返回各种错误。

==4827== Thread 3:
==4827== Invalid free() / delete / delete[] / realloc()
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Address 0x5420070 is 48 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
==4827== Thread 1:
==4827== Invalid read of size 8
==4827==    at 0x400CD3: main (in /home/test)
==4827==  Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
==4827== Invalid read of size 8
==4827==    at 0x400CFF: main (in /home/test)
==4827==  Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
==4827== Invalid read of size 8
==4827==    at 0x400D30: main (in /home/test)
==4827==  Address 0x5420060 is 32 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
tstop
==4827== Invalid write of size 8
==4827==    at 0x400D5B: main (in /home/test)
==4827==  Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
tstop
==4827== Invalid free() / delete / delete[] / realloc()
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400D8C: main (in /home/test)
==4827==  Address 0x5420040 is 0 bytes inside a block of size 96 free'd
==4827==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400E31: my_handler (in /home/test)
==4827==    by 0x4E416F9: start_thread (pthread_create.c:333)
==4827==  Block was alloc'd at
==4827==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827==    by 0x400B75: main (in /home/test)
==4827== 
==4827== 
==4827== HEAP SUMMARY:
==4827==     in use at exit: 1,614 bytes in 4 blocks
==4827==   total heap usage: 9 allocs, 7 frees, 3,334 bytes allocated
==4827== 
==4827== LEAK SUMMARY:
==4827==    definitely lost: 0 bytes in 0 blocks
==4827==    indirectly lost: 0 bytes in 0 blocks
==4827==      possibly lost: 0 bytes in 0 blocks
==4827==    still reachable: 1,614 bytes in 4 blocks
==4827==         suppressed: 0 bytes in 0 blocks

我猜这些错误与已经释放的内存访问和无效的free()有关 但是,我无法真正理解它们是如何以及为什么会发生的。

typedef int (*init)();
typedef int (*launch)();
typedef int (*stop)();

typedef struct stTask stTask_t;
typedef struct stEngine stEngine_t;

struct stTask
{
    char        name[10];    
    init        initTask;
    launch      launchTask;
    stop        stopTask; 
    pthread_t   tId;
};

struct stEngine
{
   int16_t  NbTasks;
   stTask_t* TaskThread;
};

static void sig_handler(int signo);
static int tinit(void);
static int tlaunch(void);
static int tstop(void);
static void* my_handler(void* params);

stTask_t array[] =
{
    {"TEST", (init)tinit, (launch)tlaunch, (stop)tstop, 0},
    {"TEST2", (init)tinit, (launch)tlaunch, (stop)tstop, 0}
};

int exitReq;
stEngine_t engine;

int main (int argc, char *argv[])
{
    struct sigaction action;
    int i;
    exitReq = 0;
    memset(&engine, 0, sizeof(stEngine_t));
    engine.NbTasks = 2;

    memset(&action, '\0', sizeof(action));
    action.sa_handler = &sig_handler;
    sigfillset(&action.sa_mask);
    action.sa_flags = 0;
    if ((sigaction(SIGTERM, &action, NULL) != 0) || (sigaction(SIGINT,  &action, NULL) != 0)) {
        exit(EXIT_FAILURE);
    }

    engine.TaskThread = malloc(engine.NbTasks * sizeof(stTask_t));

    for (i = 0; i < engine.NbTasks; i++) {
        engine.TaskThread[i] = array[i];
        engine.TaskThread[i].initTask();
        pthread_create(&engine.TaskThread[i].tId, NULL, my_handler, (void *) &engine.TaskThread[i]);
    }

    while (!exitReq) {
        //... do stuff
        sched_yield();
    }       

    for (i = 0; i < engine.NbTasks; i++) {
        (void)pthread_cancel(engine.TaskThread[i].tId);
        pthread_join(engine.TaskThread[i].tId, NULL);
        engine.TaskThread[i].stopTask();
        engine.TaskThread[i].tId = 0;
    }
    free(engine.TaskThread);
    memset(&engine, 0, sizeof(stEngine_t));          
    return 0;
}

static void sig_handler(int signo) 
{
    if (signo == SIGINT || signo == SIGTERM) {
        exitReq = 1;
    }
}

static void* my_handler(void* params)
{
    stTask_t* ptask = (stTask_t*) params;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

    while (!exitReq) {
        ptask->launchTask();
        pthread_testcancel();
    }
    free(ptask);
    pthread_exit(NULL);
}

static int tinit(void)
{
    fprintf(stdout, "%s\n", __func__);
    return 0;
}

static int tlaunch(void)
{
    fprintf(stdout, "%s\n", __func__);
    return 0;
}

static int tstop(void)
{
    fprintf(stdout, "%s\n", __func__);
    return 0;
}

通过在处理函数中添加注释:我没有错误,但在手动停止程序时仍然分配了几个字节。

    //free(ptask);

我没有收到任何错误,但手动停止程序时仍会分配几个字节。 根据需要,我将struc的地址作为pthread_create的最后一个参数传递,但我可能误解了有关内存的一些内容

==6017== HEAP SUMMARY:
==6017==     in use at exit: 1,614 bytes in 4 blocks
==6017==   total heap usage: 9 allocs, 5 frees, 3,334 bytes allocated
==6017== 
==6017== LEAK SUMMARY:
==6017==    definitely lost: 0 bytes in 0 blocks
==6017==    indirectly lost: 0 bytes in 0 blocks
==6017==      possibly lost: 0 bytes in 0 blocks
==6017==    still reachable: 1,614 bytes in 4 blocks
==6017==         suppressed: 0 bytes in 0 blocks

有人可以解释一下为什么,在这两种情况下,内存都没有正确释放?

0 个答案:

没有答案