Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A detached pthread causes memory leaks

There is a known memory leak, when terminating a process with running undetached pthreads. However, detaching the thread doesn't seem to be a solution. Consider the following minimal example:

#include <pthread.h>
#include <stdio.h>

static void* thread(void* _) {
  for(;;); return NULL;
}

int main(void) {
  pthread_attr_t attr; 
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  pthread_t tid; pthread_create(&tid, &attr, thread, NULL);
  pthread_attr_destroy(&attr);
  return 0;
}

A detached thread with an infinite loop is created and the process is immediately terminated. According to pthread_detach(3), the resources of the thread should be automatically released back to the system once the entire process is terminated. That, however, clearly isn't what's happening:

gcc -pthread c.c
valgrind --leak-check=full a.out

==9341== Command: a.out
==9341==
==9341==
==9341== HEAP SUMMARY:
==9341==     in use at exit: 272 bytes in 1 blocks
==9341==   total heap usage: 1 allocs, 0 frees, 272 bytes allocated
==9341==
==9341== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==9341==    at 0x4C2ABB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9341==    by 0x4012598: _dl_allocate_tls (dl-tls.c:296)
==9341==    by 0x4E3C7B5: pthread_create@@GLIBC_2.2.5 (allocatestack.c:579)
==9341==    by 0x400825: main (in /home/witiko/a.out)
==9341==
==9341== LEAK SUMMARY:
==9341==    definitely lost: 0 bytes in 0 blocks
==9341==    indirectly lost: 0 bytes in 0 blocks
==9341==      possibly lost: 272 bytes in 1 blocks
==9341==    still reachable: 0 bytes in 0 blocks
==9341==         suppressed: 0 bytes in 0 blocks

Should I be concerned? In the actual program I have several blocking threads, so, much like in the minimal example, I can't really pthread_join() with them. Should I be calling pthread_cancel() instead of exit()ing directly?

like image 814
Witiko Avatar asked Jan 02 '14 22:01

Witiko


People also ask

What does Pthread detach do?

The pthread_detach() function indicates that system resources for the specified thread should be reclaimed when the thread ends. If the thread is already ended, resources are reclaimed immediately. This routine does not cause the thread to end.

Can threads cause memory leaks?

A thread leak is causing a memory shortage at the server, which will cause the JVM process to throw out an OOM error. A possible thread leak in a third-party library or product.

Does Pthread cancel free memory?

Yes, it will leak memory in that case. C does not have any garbage collection -- if you allocate memory and fail to free it, it will be leaked, plain and simple. If you want to avoid leaking memory, don't call pthread_cancel .

What is memory leak stackoverflow?

A memory leak is simply dynamic memory that you allocate, but then never free.


1 Answers

Returning from main is equivalent to an exit of the whole process, so this is in effect quite a rude way to terminate your detached thread. Your thread simply hasn't terminated when the main function ends, it only does so later when the exit mechanism forces it. So valgrind is missing the release of the resources of the thread.

The fact that valgrind tells you that there is leaking memory shouldn't worry you by itself, but the fact that your thread is terminated without being able to cleanup and/or finish its task should worry you.

If you want to have your thread continue execution after your main thread ends, you should terminate main by pthread_exit instead of return. Then it is up to your detached thread to decide when to terminate itself. It could decide so, on receiving the necessary information through a state variable that is set atomically or through a mutex/condition mechanism.

like image 54
Jens Gustedt Avatar answered Oct 30 '22 01:10

Jens Gustedt