evilsong / gperftools

Automatically exported from code.google.com/p/gperftools
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

TCMalloc might deadlock in a thread calling fork() #496

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Use tcmalloc in an environment where threads might call fork. The testcase
attached (test-threadfork.c) is a small example that creates a set of threads 
and each thread allocates some memory, fork a allocates more memory.
Run the testcase with a higher number of threads and forks to trigger the issue.

What is the expected output? What do you see instead?
The expect output is to no deadlock occurs in the fork and all children process 
eventually finish. The tcmalloc contains a bug that some internal locks are 
left in a undefined state between fork, leaving the child process in a deadlock 
state.

What version of the product are you using? On what operating system?
I tested svn version r190 in a PPC64 and X86_64 Linux environment.

Please provide any additional information below.
The issue is the locks defined at src/static_vars.h, Static::pageheap_lock_ and 
each lock from Static::CentralFreeListPadded elements, needs to be in a 
consistent state in a forked version of a thread. Currently, some race issues 
might occurs if the following scenario occurs:

Thread 1                                 |  Thread 2
calls malloc()                           |
\_ tcmalloc lock Static::pageheap_lock_  |
                                         |  calls fork()
                                         |  calls malloc()
                                         |  \_ tcmalloc tries to lock the same lock

The same might occur with any lock from Static::central_cache_ elements as well.

A possible solution, presented in patch gperftools-atfork.patch, is register 2 
functions with pthread_atfork to lock all the locks in the parent just prior 
the fork() call and to unlock all the locks after the fork() call on both the 
parent and child. This patch fixes the above behavior with the testcase.

I didn't on any other platform, so we might need to add guards on non-unix 
platforms. I'm accepting suggestions.

Original issue reported on code.google.com by zatr...@gmail.com on 8 Feb 2013 at 6:49

Attachments:

GoogleCodeExporter commented 9 years ago
I rewrite the patch adding guards on the pthread_atfork call by not exposing 
the SpinLock from CentralThreadCache.

Original comment by zatr...@gmail.com on 8 Feb 2013 at 8:46

Attachments:

GoogleCodeExporter commented 9 years ago
r196 | chappedm@gmail.com | 2013-03-10 16:17:21 -0400 (Sun, 10 Mar 2013) | 6 
lines

issue-496: Fixes an issue where tcmalloc might deadlock in a thread calling fork

tcmalloc contained a bug where some internal locks were left in a undefined 
state
between fork, leaving the child process in a deadlock state. This patch fixes 
the
issue by introducing stricter locking between the parent nd child while forking.

Original comment by chapp...@gmail.com on 10 Mar 2013 at 8:17