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?

Kevin
  • 16,549
  • 8
  • 60
  • 74
lim
  • 371
  • 1
  • 4
  • 4
  • 2
    So did you try to write a program that just do pthread_create/pthread_exit (+join) and run it under valgrind? – Ha. Apr 10 '11 at 08:53
  • 2
    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. – Ronny Brendel Apr 10 '11 at 08:54
  • 1
    are you joining your threads with `pthread_join`? otherwise a leak is to be expected. – Hasturkun Apr 10 '11 at 09:52

5 Answers5

43

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.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Please look at my question http://stackoverflow.com/questions/41057644/memory-leakage-in-windows-pthread-pthread-join-does-not-deallocate-memory . This answer is useful but did not help me. – kyb Dec 09 '16 at 10:26
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()
Wyck
  • 10,311
  • 6
  • 39
  • 60
sehe
  • 374,641
  • 47
  • 450
  • 633
  • 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? – lim Apr 10 '11 at 10:23
  • 1
    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 reclaimed` – sehe Apr 10 '11 at 10:29
  • I've already read this man page. It still doesn't answer my question. – lim Apr 10 '11 at 10:32
  • 2
    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 out – sehe Apr 10 '11 at 10:34
5

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

Kartoch
  • 7,610
  • 9
  • 40
  • 68
micha
  • 51
  • 1
  • 1
  • 3
    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. – Tzunghsing David Wong Mar 22 '15 at 00:17
  • 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. – EML Jun 28 '18 at 12:18
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.

Aaron He
  • 51
  • 1
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

Kyrol
  • 3,475
  • 7
  • 34
  • 46