|
From: <sv...@va...> - 2011-02-14 11:06:06
|
Author: sewardj
Date: 2011-02-14 11:05:57 +0000 (Mon, 14 Feb 2011)
New Revision: 11553
Log:
Merge from trunk, r11520 and r11532 (drd: don't assert in the child
after threaded fork())
Modified:
branches/VALGRIND_3_6_BRANCH/drd/drd_main.c
branches/VALGRIND_3_6_BRANCH/drd/drd_thread.c
branches/VALGRIND_3_6_BRANCH/drd/drd_thread.h
Modified: branches/VALGRIND_3_6_BRANCH/drd/drd_main.c
===================================================================
--- branches/VALGRIND_3_6_BRANCH/drd/drd_main.c 2011-02-14 10:57:15 UTC (rev 11552)
+++ branches/VALGRIND_3_6_BRANCH/drd/drd_main.c 2011-02-14 11:05:57 UTC (rev 11553)
@@ -625,6 +625,18 @@
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 @@
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,
Modified: branches/VALGRIND_3_6_BRANCH/drd/drd_thread.c
===================================================================
--- branches/VALGRIND_3_6_BRANCH/drd/drd_thread.c 2011-02-14 10:57:15 UTC (rev 11552)
+++ branches/VALGRIND_3_6_BRANCH/drd/drd_thread.c 2011-02-14 11:05:57 UTC (rev 11553)
@@ -367,7 +367,7 @@
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 @@
* 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 @@
}
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 @@
}
}
+/** 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)
{
Modified: branches/VALGRIND_3_6_BRANCH/drd/drd_thread.h
===================================================================
--- branches/VALGRIND_3_6_BRANCH/drd/drd_thread.h 2011-02-14 10:57:15 UTC (rev 11552)
+++ branches/VALGRIND_3_6_BRANCH/drd/drd_thread.h 2011-02-14 11:05:57 UTC (rev 11553)
@@ -134,8 +134,9 @@
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);
|