summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/lsan/lsan_common_mac.cc2
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc47
2 files changed, 47 insertions, 2 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common_mac.cc b/compiler-rt/lib/lsan/lsan_common_mac.cc
index 20ac389d534..a158b6512ba 100644
--- a/compiler-rt/lib/lsan/lsan_common_mac.cc
+++ b/compiler-rt/lib/lsan/lsan_common_mac.cc
@@ -146,7 +146,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
}
void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
- CHECK(0 && "unimplemented");
+ StopTheWorld(callback, argument);
}
} // namespace __lsan
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc
index 281db96f672..20b8760935b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc
@@ -17,6 +17,8 @@
defined(__i386))
#include <mach/mach.h>
+#include <mach/thread_info.h>
+#include <pthread.h>
#include "sanitizer_stoptheworld.h"
@@ -44,8 +46,51 @@ class SuspendedThreadsListMac : public SuspendedThreadsList {
InternalMmapVector<SuspendedThreadInfo> threads_;
};
+struct RunThreadArgs {
+ StopTheWorldCallback callback;
+ void *argument;
+};
+
+void RunThread(void *arg) {
+ struct RunThreadArgs *run_args = (struct RunThreadArgs *)arg;
+ SuspendedThreadsListMac suspended_threads_list;
+
+ mach_port_t task;
+ kern_return_t err = task_for_pid(mach_task_self(), internal_getpid(), &task);
+ if (err != KERN_SUCCESS) {
+ VReport(1, "Getting task from pid failed (errno %d).\n", err);
+ return;
+ }
+
+ thread_array_t threads;
+ mach_msg_type_number_t num_threads;
+
+ err = task_threads(task, &threads, &num_threads);
+ if (err != KERN_SUCCESS) {
+ VReport(1, "Failed to get threads for task (errno %d).\n", err);
+ return;
+ }
+
+ thread_t thread_self = mach_thread_self();
+ for (unsigned int i = 0; i < num_threads; ++i) {
+ if (threads[i] == thread_self) continue;
+
+ thread_suspend(threads[i]);
+ suspended_threads_list.Append(threads[i]);
+ }
+
+ run_args->callback(suspended_threads_list, run_args->argument);
+
+ uptr num_suspended = suspended_threads_list.ThreadCount();
+ for (unsigned int i = 0; i < num_suspended; ++i) {
+ thread_resume(suspended_threads_list.GetThread(i));
+ }
+}
+
void StopTheWorld(StopTheWorldCallback callback, void *argument) {
- CHECK(0 && "unimplemented");
+ struct RunThreadArgs arg = {callback, argument};
+ pthread_t run_thread = (pthread_t)internal_start_thread(RunThread, &arg);
+ internal_join_thread(run_thread);
}
#if defined(__x86_64__)
OpenPOWER on IntegriCloud