valgrind memory leak errors when using pthread_create
Asked Answered
B

5

31

I'm writing a program using the pthread library. When I run my program with the command valgrind --leak-check=full, I get the following errors description:

==11784==  
==11784== **HEAP SUMMARY:**  
==11784==     in use at exit: 4,952 bytes in 18 blocks  
==11784==   total heap usage: 1,059 allocs, 1,041 frees, 51,864 bytes allocated  
==11784==  
==11784== **288 bytes** in 1 blocks are possibly lost in loss record 2 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)  
==11784==    by 0x401BC0: initdevice(char*) (in /a/fr-01/vol/home/stud/lim/workspace  /Ex3/l)  
==11784==    by 0x406D05: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **4,608 bytes** in 16 blocks are possibly lost in loss record 3 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)    
==11784==    by 0x40268F: write2device(char*, int) (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==    by 0x406D7B: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **LEAK SUMMARY:**  
==11784==    definitely lost: 0 bytes in 0 blocks  
==11784==    indirectly lost: 0 bytes in 0 blocks  
==11784==      possibly lost: 4,896 bytes in 17 blocks  
==11784==    still reachable: 56 bytes in 1 blocks  
==11784==         suppressed: 0 bytes in 0 blocks  
==11784== Reachable blocks (those to which a pointer was found) are not shown.  
==11784== To see them, rerun with: --leak-check=full --show-reachable=yes  
==11784==  
==11784== For counts of detected and suppressed errors, rerun with: -v  
==11784== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)  

Every time I call pthread_create, with a certain function - I call the function pthread_exit in the end of the function. So, after verifying this is not the problem, what could be the problem?

Boley answered 10/4, 2011 at 8:43 Comment(3)
So did you try to write a program that just do pthread_create/pthread_exit (+join) and run it under valgrind?Oxeyed
try running it with "--leak-check=full --show-reachable=yes". A guess is that structures that are duplicated might not get deleted. But without code to test it myself I can't say much.Olsen
are you joining your threads with pthread_join? otherwise a leak is to be expected.Shira
D
44

A thread's resources are not immediately released at termination, unless the thread was created with the detach state attribute set to PTHREAD_CREATE_DETACHED, or if pthread_detach is called for its pthread_t.

An undetached thread will remain terminated state until its identifier is passed to pthread_join or pthread_detach.

To sum it up, you have three options:

  1. create your thread with detached attribute set(PTHREAD_CREATE_DETACHED attribute)
  2. Detach your thread after creation (by calling pthread_detach), or
  3. Join with the terminated threads to recycle them (by calling pthread_join).

Hth.

Discrepant answered 10/4, 2011 at 14:31 Comment(1)
Please look at my question #41058144 . This answer is useful but did not help me.Tappet
E
6

You can make the thread in detached state to avoid the memory leak if the thread should not be joined (or just expires on it's own).

To explicitly create a thread as joinable or detached, the attr argument in the pthread_create() routine is used. The typical 4 step process is:

  • Declare a pthread attribute variable of the pthread_attr_t data type
  • Initialize the attribute variable with pthread_attr_init()
  • Set the attribute detached status with pthread_attr_setdetachstate()
  • When done, free library resources used by the attribute with pthread_attr_destroy()
Everetteeverglade answered 10/4, 2011 at 10:5 Comment(4)
I've checked this out a little bit, and found out that when i call 'pthread_detach' instead of pthread_exit - there's no memory leak problem like that i've mentioned above. Is it okay to do that and not write 'pthread_exit' at all?Boley
The man page says: The pthread_join() or pthread_detach() functions should eventually be called for every thread that is created so that storage associated with the thread may be reclaimedEveretteeverglade
I've already read this man page. It still doesn't answer my question.Boley
Ah, sorry: An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value shall serve as the thread's exit status You can leave it outEveretteeverglade
M
5

when not working with joinable threads the exiting thread needs to call pthread_detach(pthread_self()) in order to release all its resources.

Maineetloire answered 11/1, 2015 at 16:29 Comment(2)
pthread_detach(pthread_self()) works for me (stop valgrind from reporting memory leaks). This approach is also convenient since keep tracking of all threads started and do pthread_join() is rather hard when threads are dynamically created.Shoop
Some confusion here. Threads can be either joinable, or detached. It is an error to pthread_detach a detached thread, so it can only be called for a joinable thread. When "not working with a joinable thread", a simple return from the top-level function releases all resources.Ase
I
2

Please note that the default pthread_create behavior is "joinable" NOT DETACHED. Therefore some OS resources would still remain in the process after pthread finished, which would result in zombie pthread and leads to increased VIRTUAL/resident memory usage.

The four solution @sehe mentioned would fix this problem.

However if you thread is a long-standing one, this might not be really needed. for example, if the pthread lives through the whole life of the process.

Ieyasu answered 26/7, 2016 at 22:13 Comment(0)
A
1

In addition to the correct answers given you by other users, I suggest you to read this:

Tracking down a memory leak in multithreaded C application

Ardath answered 6/1, 2014 at 9:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.