[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