c pthread仍然可以接触

发布于 2025-02-07 13:11:32 字数 5502 浏览 1 评论 0原文

我在程序中使用了pthread。它运行良好,但Valgrind检测仍然可以触及。总是相同的字节:1654,4块。始终在Valgrind中可见相同的功能。

valgrind Log:

==29908== Memcheck, a memory error detector
==29908== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29908== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==29908== Command: ./a.out
==29908== Parent PID: 23902
==29908== 
==29908== 
==29908== HEAP SUMMARY:
==29908==     in use at exit: 1,654 bytes in 4 blocks
==29908==   total heap usage: 8 allocs, 4 frees, 2,526 bytes allocated
==29908== 
==29908== 36 bytes in 1 blocks are still reachable in loss record 1 of 4
==29908==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x401F5CE: strdup (strdup.c:42)
==29908==    by 0x4019A81: _dl_load_cache_lookup (dl-cache.c:338)
==29908==    by 0x400A989: _dl_map_object (dl-load.c:2102)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== 36 bytes in 1 blocks are still reachable in loss record 2 of 4
==29908==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x400D5A7: _dl_new_object (dl-object.c:196)
==29908==    by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==29908==    by 0x400A61A: _dl_map_object (dl-load.c:2236)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==29908==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x401330A: _dl_check_map_versions (dl-version.c:274)
==29908==    by 0x40160EC: dl_open_worker (dl-open.c:577)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908==    by 0x486EBB3: _Unwind_ForcedUnwind (unwind-forcedunwind.c:127)
==29908==    by 0x486CF05: __pthread_unwind (unwind.c:121)
==29908== 
==29908== 1,198 bytes in 1 blocks are still reachable in loss record 4 of 4
==29908==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x400D273: _dl_new_object (dl-object.c:89)
==29908==    by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==29908==    by 0x400A61A: _dl_map_object (dl-load.c:2236)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== LEAK SUMMARY:
==29908==    definitely lost: 0 bytes in 0 blocks
==29908==    indirectly lost: 0 bytes in 0 blocks
==29908==      possibly lost: 0 bytes in 0 blocks
==29908==    still reachable: 1,654 bytes in 4 blocks
==29908==         suppressed: 0 bytes in 0 blocks
==29908== 
==29908== For lists of detected and suppressed errors, rerun with: -s
==29908== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

如果将程序限制为1个线程,我将永远无法获得任何可及。如果我将其限制为低2的东西,有时我会做,有时不会。任何高(48)的东西意味着我几乎总是可以触及。

如下所示,我设法在没有太多代码的情况下重现了问题。我在做什么错?如果我没有做错任何事情,而只是pthread的事情,为什么它可以使仍然可以接触?为什么它取决于线程数量?

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUMTHREADS  2 //can be anything higher than 1 to cause still reachables

void    *thread(void *arg)
{
    (void)arg;
    pthread_exit(EXIT_SUCCESS);
}

int main(void)
{
    int         i;
    pthread_t   threads[NUMTHREADS];

    i = -1;
    while (++i < NUMTHREADS)
        pthread_create(threads + i, NULL, &thread, NULL);
    i = -1;
    while (++i < NUMTHREADS)
        pthread_join(threads[i], NULL);
    return (0);
}

I'm using pthread in my program. It runs fine but valgrind detects still reachables. Always the same bytes: 1654, 4 blocks. Always the same functions visible in valgrind.

Valgrind log:

==29908== Memcheck, a memory error detector
==29908== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29908== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==29908== Command: ./a.out
==29908== Parent PID: 23902
==29908== 
==29908== 
==29908== HEAP SUMMARY:
==29908==     in use at exit: 1,654 bytes in 4 blocks
==29908==   total heap usage: 8 allocs, 4 frees, 2,526 bytes allocated
==29908== 
==29908== 36 bytes in 1 blocks are still reachable in loss record 1 of 4
==29908==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x401F5CE: strdup (strdup.c:42)
==29908==    by 0x4019A81: _dl_load_cache_lookup (dl-cache.c:338)
==29908==    by 0x400A989: _dl_map_object (dl-load.c:2102)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== 36 bytes in 1 blocks are still reachable in loss record 2 of 4
==29908==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x400D5A7: _dl_new_object (dl-object.c:196)
==29908==    by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==29908==    by 0x400A61A: _dl_map_object (dl-load.c:2236)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==29908==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x401330A: _dl_check_map_versions (dl-version.c:274)
==29908==    by 0x40160EC: dl_open_worker (dl-open.c:577)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908==    by 0x486EBB3: _Unwind_ForcedUnwind (unwind-forcedunwind.c:127)
==29908==    by 0x486CF05: __pthread_unwind (unwind.c:121)
==29908== 
==29908== 1,198 bytes in 1 blocks are still reachable in loss record 4 of 4
==29908==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==29908==    by 0x400D273: _dl_new_object (dl-object.c:89)
==29908==    by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==29908==    by 0x400A61A: _dl_map_object (dl-load.c:2236)
==29908==    by 0x4015D36: dl_open_worker (dl-open.c:513)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x40155F9: _dl_open (dl-open.c:837)
==29908==    by 0x49DE860: do_dlopen (dl-libc.c:96)
==29908==    by 0x49DF8B7: _dl_catch_exception (dl-error-skeleton.c:208)
==29908==    by 0x49DF982: _dl_catch_error (dl-error-skeleton.c:227)
==29908==    by 0x49DE994: dlerror_run (dl-libc.c:46)
==29908==    by 0x49DE994: __libc_dlopen_mode (dl-libc.c:195)
==29908==    by 0x486E99A: pthread_cancel_init (unwind-forcedunwind.c:53)
==29908== 
==29908== LEAK SUMMARY:
==29908==    definitely lost: 0 bytes in 0 blocks
==29908==    indirectly lost: 0 bytes in 0 blocks
==29908==      possibly lost: 0 bytes in 0 blocks
==29908==    still reachable: 1,654 bytes in 4 blocks
==29908==         suppressed: 0 bytes in 0 blocks
==29908== 
==29908== For lists of detected and suppressed errors, rerun with: -s
==29908== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

If I limit the program to 1 thread, I never get any still reachables. If I limit it to something low like 2, I sometimes do, sometimes don't. Anything high (48) means I almost always get still reachables.

I managed to reproduce the problem without much code, as follows. What am I doing wrong? If I am doing nothing wrong and it's just pthread things, why is it making still reachables? And why is it semi-random depending on amount of threads?

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUMTHREADS  2 //can be anything higher than 1 to cause still reachables

void    *thread(void *arg)
{
    (void)arg;
    pthread_exit(EXIT_SUCCESS);
}

int main(void)
{
    int         i;
    pthread_t   threads[NUMTHREADS];

    i = -1;
    while (++i < NUMTHREADS)
        pthread_create(threads + i, NULL, &thread, NULL);
    i = -1;
    while (++i < NUMTHREADS)
        pthread_join(threads[i], NULL);
    return (0);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若水微香 2025-02-14 13:11:33

在您的线程函数中,您正在执行:

pthread_exit(EXIT_SUCCESS);

替换为:

return (void *) 0;

完美,谢谢。以这种方式退出线程的有缺点吗?您还知道,在Pthread中,什么是导致这些仍然可以触及的东西,或者为什么此解决方案有效? -
modin

[linux,至少] pthread_create dis not 将其提供给线程函数的参数(例如,在您的情况下,thread )作为clone syscall的线程起始地址。它给出了指向内部/隐藏的“助手”启动功能的指针,该功能可以:

  1. 线程本地存储等的一些初始化(可能需要调用malloc)。
  2. 调用“真实”功能
  3. TLS清理/驱动器,

如果我们调用pthread_exit,我们正在绕过步骤(3)。

要查看详细信息,我们必须获取glibc来源,然后查看nptl/pthread_create.c 到10个左右的步骤,这些步骤绕过,这些步骤又通过不返回而绕开。

就我个人而言,我总是“解开”我的调用堆栈以使用return(void *),并且仅称为pthread_exit作为“ Abort”


编辑:

如果我们查看pthread_exit的来源,它将调用__ do_cancel [内部函数]。因此,就像是这样:

pthread_cancel(pthread_self());

给定[修改]程序:

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUMTHREADS  8                   // can be anything higher than 1 to cause still reachables

void *
thread(void *arg)
{
#if DOEXIT
    (void) arg;
    pthread_exit(EXIT_SUCCESS);
#else
    return (void *) 0;
#endif
}

int
main(void)
{
    int i;
    pthread_t threads[NUMTHREADS];

    i = -1;
    while (++i < NUMTHREADS)
        pthread_create(threads + i, NULL, &thread, NULL);
    i = -1;
    while (++i < NUMTHREADS)
        pthread_join(threads[i], NULL);
    return (0);
}

在下面的测试输出中注意,valgrind命令是:

valgrind --leak-check=full --show-leak-kinds=all -s ./fix0

这是用-ddoexit = 1(确实pthread_exit):

==1659955== Memcheck, a memory error detector
==1659955== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1659955== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==1659955== Command: ./fix0
==1659955==
==1659955==
==1659955== HEAP SUMMARY:
==1659955==     in use at exit: 1,616 bytes in 4 blocks
==1659955==   total heap usage: 13 allocs, 9 frees, 3,848 bytes allocated
==1659955==
==1659955== 21 bytes in 1 blocks are still reachable in loss record 1 of 4
==1659955==    at 0x483780B: malloc (vg_replace_malloc.c:309)
==1659955==    by 0x401C13D: strdup (strdup.c:42)
==1659955==    by 0x4016D0A: _dl_load_cache_lookup (dl-cache.c:306)
==1659955==    by 0x4009592: _dl_map_object (dl-load.c:2107)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== 21 bytes in 1 blocks are still reachable in loss record 2 of 4
==1659955==    at 0x483780B: malloc (vg_replace_malloc.c:309)
==1659955==    by 0x400BCEF: _dl_new_object (dl-object.c:163)
==1659955==    by 0x400649F: _dl_map_object_from_fd (dl-load.c:1002)
==1659955==    by 0x4009319: _dl_map_object (dl-load.c:2241)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==1659955==    at 0x4839B1A: calloc (vg_replace_malloc.c:762)
==1659955==    by 0x401142F: _dl_check_map_versions (dl-version.c:274)
==1659955==    by 0x4013B25: dl_open_worker (dl-open.c:266)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==    by 0x48AE45A: pthread_cancel_init (unwind-forcedunwind.c:53)
==1659955==    by 0x48AE673: _Unwind_ForcedUnwind (unwind-forcedunwind.c:127)
==1659955==
==1659955== 1,190 bytes in 1 blocks are still reachable in loss record 4 of 4
==1659955==    at 0x4839B1A: calloc (vg_replace_malloc.c:762)
==1659955==    by 0x400BA11: _dl_new_object (dl-object.c:73)
==1659955==    by 0x400649F: _dl_map_object_from_fd (dl-load.c:1002)
==1659955==    by 0x4009319: _dl_map_object (dl-load.c:2241)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== LEAK SUMMARY:
==1659955==    definitely lost: 0 bytes in 0 blocks
==1659955==    indirectly lost: 0 bytes in 0 blocks
==1659955==      possibly lost: 0 bytes in 0 blocks
==1659955==    still reachable: 1,616 bytes in 4 blocks
==1659955==         suppressed: 0 bytes in 0 blocks
==1659955==
==1659955== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

以下是使用-ddoexit = 0编译时的输出(dies return> return(void *)0;):

==1660133== Memcheck, a memory error detector
==1660133== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1660133== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==1660133== Command: ./fix0
==1660133==
==1660133==
==1660133== HEAP SUMMARY:
==1660133==     in use at exit: 0 bytes in 0 blocks
==1660133==   total heap usage: 8 allocs, 8 frees, 2,176 bytes allocated
==1660133==
==1660133== All heap blocks were freed -- no leaks are possible
==1660133==
==1660133== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

In your thread function, you are doing:

pthread_exit(EXIT_SUCCESS);

Replace with:

return (void *) 0;

Perfect, thank you. Any downsides to exiting threads this way? Do you also have any idea what in pthread is causing these still reachables or why this solution works? –
Modin

The [linux, at least] implementation of pthread_create does not put the argument you give it for the thread function (e.g. in your case thread) as the thread start address given to the clone syscall. It gives the pointer to an internal/hidden "helper" start function that does:

  1. Some initialization of thread local storage, etc (which may need to call malloc).
  2. Invokes the "real" function
  3. TLS cleanup/destructors

If we call pthread_exit, we are bypassing step (3).

To see the details, we'd have to get the glibc source and look in nptl/pthread_create.c to the 10 or so steps that get bypassed by not returning.

Personally, I've always "unwound" my call stack to use the return (void *) and only called pthread_exit as an "abort"


Edit:

If we look at the source for pthread_exit, it calls __do_cancel [an internal function]. So, it's like doing:

pthread_cancel(pthread_self());

Given the [modified] program:

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define NUMTHREADS  8                   // can be anything higher than 1 to cause still reachables

void *
thread(void *arg)
{
#if DOEXIT
    (void) arg;
    pthread_exit(EXIT_SUCCESS);
#else
    return (void *) 0;
#endif
}

int
main(void)
{
    int i;
    pthread_t threads[NUMTHREADS];

    i = -1;
    while (++i < NUMTHREADS)
        pthread_create(threads + i, NULL, &thread, NULL);
    i = -1;
    while (++i < NUMTHREADS)
        pthread_join(threads[i], NULL);
    return (0);
}

Note in the test outputs below, the valgrind command is:

valgrind --leak-check=full --show-leak-kinds=all -s ./fix0

Here is the output compiled with -DDOEXIT=1 (that does pthread_exit):

==1659955== Memcheck, a memory error detector
==1659955== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1659955== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==1659955== Command: ./fix0
==1659955==
==1659955==
==1659955== HEAP SUMMARY:
==1659955==     in use at exit: 1,616 bytes in 4 blocks
==1659955==   total heap usage: 13 allocs, 9 frees, 3,848 bytes allocated
==1659955==
==1659955== 21 bytes in 1 blocks are still reachable in loss record 1 of 4
==1659955==    at 0x483780B: malloc (vg_replace_malloc.c:309)
==1659955==    by 0x401C13D: strdup (strdup.c:42)
==1659955==    by 0x4016D0A: _dl_load_cache_lookup (dl-cache.c:306)
==1659955==    by 0x4009592: _dl_map_object (dl-load.c:2107)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== 21 bytes in 1 blocks are still reachable in loss record 2 of 4
==1659955==    at 0x483780B: malloc (vg_replace_malloc.c:309)
==1659955==    by 0x400BCEF: _dl_new_object (dl-object.c:163)
==1659955==    by 0x400649F: _dl_map_object_from_fd (dl-load.c:1002)
==1659955==    by 0x4009319: _dl_map_object (dl-load.c:2241)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==1659955==    at 0x4839B1A: calloc (vg_replace_malloc.c:762)
==1659955==    by 0x401142F: _dl_check_map_versions (dl-version.c:274)
==1659955==    by 0x4013B25: dl_open_worker (dl-open.c:266)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==    by 0x48AE45A: pthread_cancel_init (unwind-forcedunwind.c:53)
==1659955==    by 0x48AE673: _Unwind_ForcedUnwind (unwind-forcedunwind.c:127)
==1659955==
==1659955== 1,190 bytes in 1 blocks are still reachable in loss record 4 of 4
==1659955==    at 0x4839B1A: calloc (vg_replace_malloc.c:762)
==1659955==    by 0x400BA11: _dl_new_object (dl-object.c:73)
==1659955==    by 0x400649F: _dl_map_object_from_fd (dl-load.c:1002)
==1659955==    by 0x4009319: _dl_map_object (dl-load.c:2241)
==1659955==    by 0x4013A7D: dl_open_worker (dl-open.c:217)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x401363D: _dl_open (dl-open.c:588)
==1659955==    by 0x49F5250: do_dlopen (dl-libc.c:96)
==1659955==    by 0x49F5D66: _dl_catch_exception (dl-error-skeleton.c:196)
==1659955==    by 0x49F5E02: _dl_catch_error (dl-error-skeleton.c:215)
==1659955==    by 0x49F5356: dlerror_run (dl-libc.c:46)
==1659955==    by 0x49F53E9: __libc_dlopen_mode (dl-libc.c:195)
==1659955==
==1659955== LEAK SUMMARY:
==1659955==    definitely lost: 0 bytes in 0 blocks
==1659955==    indirectly lost: 0 bytes in 0 blocks
==1659955==      possibly lost: 0 bytes in 0 blocks
==1659955==    still reachable: 1,616 bytes in 4 blocks
==1659955==         suppressed: 0 bytes in 0 blocks
==1659955==
==1659955== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Here is the output when compiled with -DDOEXIT=0 (does return (void *) 0;):

==1660133== Memcheck, a memory error detector
==1660133== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1660133== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==1660133== Command: ./fix0
==1660133==
==1660133==
==1660133== HEAP SUMMARY:
==1660133==     in use at exit: 0 bytes in 0 blocks
==1660133==   total heap usage: 8 allocs, 8 frees, 2,176 bytes allocated
==1660133==
==1660133== All heap blocks were freed -- no leaks are possible
==1660133==
==1660133== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文