From: Bart Van Assche Date: Thu, 3 Feb 2011 17:47:50 +0000 (+0000) Subject: DRD: do not assert() upon fork(). Fixes the DRD part of #255355. X-Git-Tag: svn/VALGRIND_3_7_0~684 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79f1b0152087ee30f8f139f22415f339a3f486bf;p=thirdparty%2Fvalgrind.git DRD: do not assert() upon fork(). Fixes the DRD part of #255355. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11520 --- diff --git a/drd/drd_main.c b/drd/drd_main.c index e317857ff3..ebf08459ba 100644 --- a/drd/drd_main.c +++ b/drd/drd_main.c @@ -627,6 +627,18 @@ static void drd_thread_finished(ThreadId vg_tid) DRD_(thread_finished)(drd_tid); } +/* + * Called immediately after fork for the child process only. 'tid' is the + * only surviving thread in the child process. Cleans up thread state. + * See also http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html for a detailed discussion of using fork() in combination with mutexes. + */ +static +void drd__atfork_child(ThreadId tid) +{ + DRD_(drd_thread_atfork_child)(tid); +} + + // // Implementation of the tool interface. // @@ -756,6 +768,8 @@ void drd_pre_clo_init(void) VG_(track_pre_thread_ll_create) (drd_pre_thread_create); VG_(track_pre_thread_first_insn)(drd_post_thread_create); VG_(track_pre_thread_ll_exit) (drd_thread_finished); + VG_(atfork) (NULL/*pre*/, NULL/*parent*/, + drd__atfork_child/*child*/); // Other stuff. DRD_(register_malloc_wrappers)(drd_start_using_mem_w_ecu, diff --git a/drd/drd_thread.c b/drd/drd_thread.c index 909bb45a19..f85a5b0923 100644 --- a/drd/drd_thread.c +++ b/drd/drd_thread.c @@ -504,6 +504,21 @@ void DRD_(thread_finished)(const DrdThreadId tid) } } +/** Called just after fork() in the child process. */ +void DRD_(drd_thread_atfork_child)(const DrdThreadId tid) +{ + unsigned i; + + for (i = 1; i < DRD_N_THREADS; i++) + { + if (i == tid) + continue; + if (DRD_(IsValidDrdThreadId(i))) + DRD_(thread_delete)(i); + tl_assert(!DRD_(IsValidDrdThreadId(i))); + } +} + /** Called just before pthread_cancel(). */ void DRD_(thread_pre_cancel)(const DrdThreadId tid) { diff --git a/drd/drd_thread.h b/drd/drd_thread.h index cb4853b01d..920df4a28c 100644 --- a/drd/drd_thread.h +++ b/drd/drd_thread.h @@ -136,6 +136,7 @@ DrdThreadId DRD_(thread_post_create)(const ThreadId vg_created); void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee); void DRD_(thread_delete)(const DrdThreadId tid); void DRD_(thread_finished)(const DrdThreadId tid); +void DRD_(drd_thread_atfork_child)(const DrdThreadId tid); void DRD_(thread_pre_cancel)(const DrdThreadId tid); void DRD_(thread_set_stack_startup)(const DrdThreadId tid, const Addr stack_startup);