c pthread仍然可以接触
我在程序中使用了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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的
线程
函数中,您正在执行:替换为:
[linux,至少]
pthread_create
dis not 将其提供给线程函数的参数(例如,在您的情况下,thread
)作为clone
syscall的线程起始地址。它给出了指向内部/隐藏的“助手”启动功能的指针,该功能可以:malloc
)。如果我们调用
pthread_exit
,我们正在绕过步骤(3)。要查看详细信息,我们必须获取
glibc
来源,然后查看nptl/pthread_create.c
到10个左右的步骤,这些步骤绕过,这些步骤又通过不返回而绕开。就我个人而言,我总是“解开”我的调用堆栈以使用
return(void *)
,并且仅称为pthread_exit
作为“ Abort”编辑:
如果我们查看
pthread_exit
的来源,它将调用__ do_cancel
[内部函数]。因此,就像是这样:给定[修改]程序:
在下面的测试输出中注意,
valgrind
命令是:这是用
-ddoexit = 1
(确实pthread_exit
):以下是使用
-ddoexit = 0
编译时的输出(diesreturn> return(void *)0;
):In your
thread
function, you are doing:Replace with:
The [linux, at least] implementation of
pthread_create
does not put the argument you give it for the thread function (e.g. in your casethread
) as the thread start address given to theclone
syscall. It gives the pointer to an internal/hidden "helper" start function that does:malloc
).If we call
pthread_exit
, we are bypassing step (3).To see the details, we'd have to get the
glibc
source and look innptl/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 calledpthread_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:Given the [modified] program:
Note in the test outputs below, the
valgrind
command is:Here is the output compiled with
-DDOEXIT=1
(that doespthread_exit
):Here is the output when compiled with
-DDOEXIT=0
(doesreturn (void *) 0;
):