Merge (from branches/THRCHECK) the following two changes to the core-tool
interface:
r6805: Modify two thread-notification events in the core-tool
interface. This removes track_post_thread_create and
track_post_thread_join. The core can only see low level thread
creation and exiting, and has no idea about pthread-level concepts
like "pthread_create" and "pthread_join", so these are a bit
ambiguous.
Replace them with track_pre_thread_ll_create, which is notified before
a new thread makes any memory references, and
track_pre_thread_ll_exit, which is notified just before the new thread
exits, that is, after it has made its last memory reference.
r6823: Core-tool interface: give 'needs_tool_errors' an extra Boolean
indicating whether or not the core should print thread id's on error
messages.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7123 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c
index 40e91fc..b719dcb 100644
--- a/coregrind/m_errormgr.c
+++ b/coregrind/m_errormgr.c
@@ -293,7 +293,8 @@
}
if (!VG_(clo_xml)) {
- if (err->tid > 0 && err->tid != last_tid_printed) {
+ if (VG_(tdict).tool_show_ThreadIDs_for_errors
+ && err->tid > 0 && err->tid != last_tid_printed) {
VG_(message)(Vg_UserMsg, "Thread %d:", err->tid );
last_tid_printed = err->tid;
}
@@ -380,7 +381,7 @@
err->count = 1;
err->tid = tid;
if (NULL == where)
- err->where = VG_(record_ExeContext)( tid );
+ err->where = VG_(record_ExeContext)( tid, 0 );
else
err->where = where;
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index 335a112..1c1d24b 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -267,6 +267,12 @@
ctst->client_stack_szB = 0;
}
+ /* Assume the clone will succeed, and tell any tool that wants to
+ know that this thread has come into existence. If the clone
+ fails, we'll send out a ll_exit notification for it at the out:
+ label below, to clean up. */
+ VG_TRACK ( pre_thread_ll_create, ptid, ctid );
+
if (flags & VKI_CLONE_SETTLS) {
if (debug)
VG_(printf)("clone child has SETTLS: tls at %p\n", tlsaddr);
@@ -292,6 +298,8 @@
/* clone failed */
VG_(cleanup_thread)(&ctst->arch);
ctst->status = VgTs_Empty;
+ /* oops. Better tell the tool the thread exited in a hurry :-) */
+ VG_TRACK( pre_thread_ll_exit, ctid );
}
return res;
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 71cc34c..88b160c 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -78,8 +78,6 @@
VG_(printf)("thread tid %d started: stack = %p\n",
tid, &tid);
- VG_TRACK ( post_thread_create, tst->os_state.parent, tid );
-
tst->os_state.lwpid = VG_(gettid)();
tst->os_state.threadgroup = VG_(getpid)();
@@ -128,6 +126,9 @@
c = VG_(count_living_threads)();
vg_assert(c >= 1); /* stay sane */
+ // Tell the tool this thread is exiting
+ VG_TRACK( pre_thread_ll_exit, tid );
+
if (c == 1) {
VG_(debugLog)(1, "syswrap-linux",
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
index faec292..9426d0b 100644
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
@@ -313,6 +313,12 @@
ctst->client_stack_szB = 0;
}
+ /* Assume the clone will succeed, and tell any tool that wants to
+ know that this thread has come into existence. If the clone
+ fails, we'll send out a ll_exit notification for it at the out:
+ label below, to clean up. */
+ VG_TRACK ( pre_thread_ll_create, ptid, ctid );
+
if (flags & VKI_CLONE_SETTLS) {
if (debug)
VG_(printf)("clone child has SETTLS: tls at %p\n", child_tls);
@@ -344,6 +350,8 @@
/* clone failed */
VG_(cleanup_thread)(&ctst->arch);
ctst->status = VgTs_Empty;
+ /* oops. Better tell the tool the thread exited in a hurry :-) */
+ VG_TRACK( pre_thread_ll_exit, ctid );
}
return res;
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
index 6907401..9ebe705 100644
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
@@ -341,6 +341,12 @@
ctst->client_stack_szB = 0;
}
+ /* Assume the clone will succeed, and tell any tool that wants to
+ know that this thread has come into existence. If the clone
+ fails, we'll send out a ll_exit notification for it at the out:
+ label below, to clean up. */
+ VG_TRACK ( pre_thread_ll_create, ptid, ctid );
+
if (flags & VKI_CLONE_SETTLS) {
if (debug)
VG_(printf)("clone child has SETTLS: tls at %p\n", child_tls);
@@ -374,6 +380,8 @@
/* clone failed */
VG_(cleanup_thread)(&ctst->arch);
ctst->status = VgTs_Empty;
+ /* oops. Better tell the tool the thread exited in a hurry :-) */
+ VG_TRACK( pre_thread_ll_exit, ctid );
}
return res;
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index 6a94865..001d2a8 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -279,6 +279,15 @@
ctst->client_stack_szB = 0;
}
+ /* Assume the clone will succeed, and tell any tool that wants to
+ know that this thread has come into existence. We cannot defer
+ it beyond this point because sys_set_thread_area, just below,
+ causes tCheck to assert by making references to the new ThreadId
+ if we don't state the new thread exists prior to that point.
+ If the clone fails, we'll send out a ll_exit notification for it
+ at the out: label below, to clean up. */
+ VG_TRACK ( pre_thread_ll_create, ptid, ctid );
+
if (flags & VKI_CLONE_SETTLS) {
if (debug)
VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d "
@@ -311,6 +320,8 @@
/* clone failed */
VG_(cleanup_thread)(&ctst->arch);
ctst->status = VgTs_Empty;
+ /* oops. Better tell the tool the thread exited in a hurry :-) */
+ VG_TRACK( pre_thread_ll_exit, ctid );
}
return res;
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
index a5b8fbb..b7440ca 100644
--- a/coregrind/m_tooliface.c
+++ b/coregrind/m_tooliface.c
@@ -176,6 +176,7 @@
void VG_(needs_tool_errors)(
Bool (*eq) (VgRes, Error*, Error*),
void (*pp) (Error*),
+ Bool show_TIDs,
UInt (*update) (Error*),
Bool (*recog) (Char*, Supp*),
Bool (*read_extra) (Int, Char*, Int, Supp*),
@@ -187,6 +188,7 @@
VG_(needs).tool_errors = True;
VG_(tdict).tool_eq_Error = eq;
VG_(tdict).tool_pp_Error = pp;
+ VG_(tdict).tool_show_ThreadIDs_for_errors = show_TIDs;
VG_(tdict).tool_update_extra = update;
VG_(tdict).tool_recognised_suppression = recog;
VG_(tdict).tool_read_extra_suppression_info = read_extra;
@@ -332,8 +334,8 @@
DEF(track_start_client_code, ThreadId, ULong)
DEF(track_stop_client_code, ThreadId, ULong)
-DEF(track_post_thread_create, ThreadId, ThreadId)
-DEF(track_post_thread_join, ThreadId, ThreadId)
+DEF(track_pre_thread_ll_create, ThreadId, ThreadId)
+DEF(track_pre_thread_ll_exit, ThreadId)
DEF(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
DEF(track_post_deliver_signal, ThreadId, Int sigNo)
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
index 3fa45c4..f6690fe 100644
--- a/coregrind/pub_core_tooliface.h
+++ b/coregrind/pub_core_tooliface.h
@@ -118,6 +118,7 @@
// VG_(needs).tool_errors
Bool (*tool_eq_Error) (VgRes, Error*, Error*);
void (*tool_pp_Error) (Error*);
+ Bool tool_show_ThreadIDs_for_errors;
UInt (*tool_update_extra) (Error*);
Bool (*tool_recognised_suppression) (Char*, Supp*);
Bool (*tool_read_extra_suppression_info) (Int, Char*, Int, Supp*);
@@ -207,8 +208,8 @@
void (*track_start_client_code)(ThreadId, ULong);
void (*track_stop_client_code) (ThreadId, ULong);
- void (*track_post_thread_create)(ThreadId, ThreadId);
- void (*track_post_thread_join) (ThreadId, ThreadId);
+ void (*track_pre_thread_ll_create)(ThreadId, ThreadId);
+ void (*track_pre_thread_ll_exit) (ThreadId);
void (*track_pre_deliver_signal) (ThreadId, Int sigNo, Bool);
void (*track_post_deliver_signal)(ThreadId, Int sigNo);
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
index f2012dc..b836833 100644
--- a/include/pub_tool_tooliface.h
+++ b/include/pub_tool_tooliface.h
@@ -303,6 +303,9 @@
// Print error context.
void (*pp_Error)(Error* err),
+ // Should the core indicate which ThreadId each error comes from?
+ Bool show_ThreadIDs_for_errors,
+
// Should fill in any details that could be postponed until after the
// decision whether to ignore the error (ie. details not affecting the
// result of VG_(tdict).tool_eq_Error()). This saves time when errors
@@ -544,13 +547,14 @@
/* Scheduler events (not exhaustive) */
/* Called when 'tid' starts or stops running client code blocks.
- Gives the total dispatched block count at that event. Note, this is
- not the same as 'tid' holding the BigLock (the lock that ensures that
- only one thread runs at a time): a thread can hold the lock for other
- purposes (making translations, etc) yet not be running client blocks.
- Obviously though, a thread must hold the lock in order to run client
- code blocks, so the times bracketed by 'thread_run'..'thread_runstate'
- are a subset of the times when thread 'tid' holds the cpu lock.
+ Gives the total dispatched block count at that event. Note, this
+ is not the same as 'tid' holding the BigLock (the lock that ensures
+ that only one thread runs at a time): a thread can hold the lock
+ for other purposes (making translations, etc) yet not be running
+ client blocks. Obviously though, a thread must hold the lock in
+ order to run client code blocks, so the times bracketed by
+ 'start_client_code'..'stop_client_code' are a subset of the times
+ when thread 'tid' holds the cpu lock.
*/
void VG_(track_start_client_code)(
void(*f)(ThreadId tid, ULong blocks_dispatched)
@@ -562,11 +566,16 @@
/* Thread events (not exhaustive)
- Called during thread create, before the new thread has run any
- instructions (or touched any memory).
- */
-void VG_(track_post_thread_create)(void(*f)(ThreadId tid, ThreadId child));
-void VG_(track_post_thread_join) (void(*f)(ThreadId joiner, ThreadId joinee));
+ ll_create: low level thread creation. Called before the new thread
+ has run any instructions (or touched any memory). In fact, called
+ immediately before the new thread has come into existence; the new
+ thread can be assumed to exist when notified by this call.
+
+ ll_exit: low level thread exit. Called after the exiting thread
+ has run its last instruction.
+*/
+void VG_(track_pre_thread_ll_create)(void(*f)(ThreadId tid, ThreadId child));
+void VG_(track_pre_thread_ll_exit) (void(*f)(ThreadId tid));
/* Signal events (not exhaustive)