OSDN Git Service

Eliminate deadlock in forked child due to delayed resetting mutex lock
authorMingwei Shi <mingwei.shi@intel.com>
Thu, 3 Nov 2016 14:53:45 +0000 (14:53 +0000)
committerMingwei Shi <mingwei.shi@intel.com>
Mon, 7 Nov 2016 03:32:57 +0000 (03:32 +0000)
commitf6a21bfac5abf7c6fc121ca1caa78528690a25dd
tree3fe32d243b3fede11b25398e85a10aff1a5599c3
parent42eb0b255507ca4d3b4e94b7756c15ab742261c0
Eliminate deadlock in forked child due to delayed resetting mutex lock

For some program implementation, the pattern like below, calling
pthread_atfork to register atfork interfaces.

    pthread_atfork(&atfork_prepare, &atfork_parent, &atfork_child);

When the program is expected to reopen the shared library's handle
inherited from parent in child process. Maybe, dlclose is called in
atfork_child to release the shared library handle before reopen it.
Then, dlclose will indrectly call _cxa_finalize and finaly call
__unregister_atfork when dso is not NULL.

    atfork_child() -> dlclose() -> __on_dlclose()
     -> __cxa_finalize() -> __unregister_atfork(dso)

In __unregister_atfork, firstly, it try to hold the g_atfork_list_mutex
lock to operate the g_atfork_list. Due to the registered atfork_child is
executed before resetting g_atfork_list_mutex lock in child, the child
process will be blocked here because of deadlock.

Test: bionic-unit-tests32 --gtest_filter=pthread.pthread_atfork_child_with_dlclose
without the fixing, the test will be timeout.

Change-Id: I35d3001682c836e0955d6d681bc5f9297fad0c7b
Signed-off-by: Mingwei Shi <mingwei.shi@intel.com>
Signed-off-by: Qiming Shi <qiming.shi@intel.com>
Signed-off-by: Chao Xie <chao.xie@intel.com>
libc/bionic/pthread_atfork.cpp
tests/pthread_dlfcn_test.cpp