[PATCH] [sanitizer] Handle Die() in StopTheWorld.
Sergey Matveev
earthdok at google.com
Mon Aug 26 04:48:13 PDT 2013
- address kcc's comments
Hi kcc,
http://llvm-reviews.chandlerc.com/D1515
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1515?vs=3749&id=3750#toc
Files:
lib/sanitizer_common/sanitizer_common.cc
lib/sanitizer_common/sanitizer_common.h
lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
Index: lib/sanitizer_common/sanitizer_common.cc
===================================================================
--- lib/sanitizer_common/sanitizer_common.cc
+++ lib/sanitizer_common/sanitizer_common.cc
@@ -37,11 +37,15 @@
// child thread will be different from |report_fd_pid|.
static uptr report_fd_pid = 0;
-static void (*DieCallback)(void);
-void SetDieCallback(void (*callback)(void)) {
+static DieCallbackType DieCallback;
+void SetDieCallback(DieCallbackType callback) {
DieCallback = callback;
}
+DieCallbackType GetDieCallback() {
+ return DieCallback;
+}
+
void NORETURN Die() {
if (DieCallback) {
DieCallback();
Index: lib/sanitizer_common/sanitizer_common.h
===================================================================
--- lib/sanitizer_common/sanitizer_common.h
+++ lib/sanitizer_common/sanitizer_common.h
@@ -165,7 +165,9 @@
// Specific tools may override behavior of "Die" and "CheckFailed" functions
// to do tool-specific job.
-void SetDieCallback(void (*callback)(void));
+typedef void (*DieCallbackType)(void);
+void SetDieCallback(DieCallbackType);
+DieCallbackType GetDieCallback();
typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
u64, u64);
void SetCheckFailedCallback(CheckFailedCallbackType callback);
Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
@@ -191,6 +191,8 @@
BlockingMutex mutex;
};
+static DieCallbackType old_die_callback;
+
// Signal handler to wake up suspended threads when the tracer thread dies.
void TracerThreadSignalHandler(int signum, siginfo_t *siginfo, void *) {
if (thread_suspender_instance != NULL) {
@@ -202,6 +204,17 @@
internal__exit((signum == SIGABRT) ? 1 : 2);
}
+static void TracerThreadDieCallback() {
+ // This really only works correctly if all the threads are suspended at this
+ // point. So we correctly handle calls to Die() from within the callback, but
+ // not those that happen before or after the callback. Hopefully there aren't
+ // a lot of opportunities for that to happen...
+ if (thread_suspender_instance)
+ thread_suspender_instance->KillAllThreads();
+ if (old_die_callback)
+ old_die_callback();
+}
+
// Size of alternative stack for signal handlers in the tracer thread.
static const int kHandlerStackSize = 4096;
@@ -214,6 +227,8 @@
tracer_thread_argument->mutex.Lock();
tracer_thread_argument->mutex.Unlock();
+ SetDieCallback(TracerThreadDieCallback);
+
ThreadSuspender thread_suspender(internal_getppid());
// Global pointer for the signal handler.
thread_suspender_instance = &thread_suspender;
@@ -326,6 +341,7 @@
// Block the execution of TracerThread until after we have set ptrace
// permissions.
tracer_thread_argument.mutex.Lock();
+ old_die_callback = GetDieCallback();
pid_t tracer_pid = clone(TracerThread, tracer_stack.Bottom(),
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_UNTRACED,
&tracer_thread_argument);
@@ -349,6 +365,7 @@
if (internal_iserror(waitpid_status, &wperrno))
Report("Waiting on the tracer thread failed (errno %d).\n", wperrno);
}
+ SetDieCallback(old_die_callback);
// Restore the dumpable flag.
if (!process_was_dumpable)
internal_prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1515.2.patch
Type: text/x-patch
Size: 3547 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130826/57d2686e/attachment.bin>
More information about the llvm-commits
mailing list