]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge from trunk, r11520 and r11532 (drd: don't assert in the child
authorJulian Seward <jseward@acm.org>
Mon, 14 Feb 2011 11:05:57 +0000 (11:05 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 14 Feb 2011 11:05:57 +0000 (11:05 +0000)
after threaded fork())

git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_6_BRANCH@11553

drd/drd_main.c
drd/drd_thread.c
drd/drd_thread.h

index 953120b7543e26e5b3de48e653ce139bd06e1fe3..712ce4ce190895638900310b973ffd63787c27ee 100644 (file)
@@ -625,6 +625,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.
 //
@@ -754,6 +766,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,
index 909bb45a1989bf237261fecb015a694eb2bf9688..a31531ed9de63ef27c81f5f12c6f2809c29d7e68 100644 (file)
@@ -367,7 +367,7 @@ void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee)
                                DRD_(thread_get_stack_max)(drd_joinee));
    }
    DRD_(clientobj_delete_thread)(drd_joinee);
-   DRD_(thread_delete)(drd_joinee);
+   DRD_(thread_delete)(drd_joinee, False);
 }
 
 /**
@@ -450,7 +450,7 @@ Int DRD_(thread_get_threads_on_alt_stack)(void)
  * Clean up thread-specific data structures. Call this just after
  * pthread_join().
  */
-void DRD_(thread_delete)(const DrdThreadId tid)
+void DRD_(thread_delete)(const DrdThreadId tid, const Bool detached)
 {
    Segment* sg;
    Segment* sg_prev;
@@ -467,7 +467,10 @@ void DRD_(thread_delete)(const DrdThreadId tid)
    }
    DRD_(g_threadinfo)[tid].vg_thread_exists = False;
    DRD_(g_threadinfo)[tid].posix_thread_exists = False;
-   tl_assert(DRD_(g_threadinfo)[tid].detached_posix_thread == False);
+   if (detached)
+      DRD_(g_threadinfo)[tid].detached_posix_thread = False;
+   else
+      tl_assert(!DRD_(g_threadinfo)[tid].detached_posix_thread);
    DRD_(g_threadinfo)[tid].first = 0;
    DRD_(g_threadinfo)[tid].last = 0;
 
@@ -504,6 +507,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, True);
+      tl_assert(!DRD_(IsValidDrdThreadId(i)));
+   }   
+}
+
 /** Called just before pthread_cancel(). */
 void DRD_(thread_pre_cancel)(const DrdThreadId tid)
 {
index cb4853b01dcf3aa90167b7f5100310809cd7a7d5..8d63467acf6cef469dab3b892398732a7e2ee820 100644 (file)
@@ -134,8 +134,9 @@ DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator,
                                     const ThreadId vg_created);
 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_delete)(const DrdThreadId tid, Bool detached);
 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);