Index: runtime/vm/thread_interrupter_macos.cc |
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc |
index fb9e145f019fd5a565fb56858176a437879093ba..e37580d0e5ead5bb6c2c3151971cd6fa624500e6 100644 |
--- a/runtime/vm/thread_interrupter_macos.cc |
+++ b/runtime/vm/thread_interrupter_macos.cc |
@@ -6,6 +6,11 @@ |
#if defined(TARGET_OS_MACOS) |
#include <errno.h> // NOLINT |
+#include <assert.h> // NOLINT |
+#include <stdbool.h> // NOLINT |
+#include <sys/types.h> // NOLINT |
+#include <unistd.h> // NOLINT |
+#include <sys/sysctl.h> // NOLINT |
#include "vm/flags.h" |
#include "vm/os.h" |
@@ -20,6 +25,27 @@ namespace dart { |
DECLARE_FLAG(bool, thread_interrupter); |
DECLARE_FLAG(bool, trace_thread_interrupter); |
+// Returns true if the current process is being debugged (either |
+// running under the debugger or has a debugger attached post facto). |
+// Code from https://developer.apple.com/library/content/qa/qa1361/_index.html |
+bool ThreadInterrupter::IsDebuggerAttached() { |
+ struct kinfo_proc info; |
+ // Initialize the flags so that, if sysctl fails for some bizarre |
+ // reason, we get a predictable result. |
+ info.kp_proc.p_flag = 0; |
+ // Initialize mib, which tells sysctl the info we want, in this case |
+ // we're looking for information about a specific process ID. |
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; |
+ size_t size = sizeof(info); |
+ |
+ // Call sysctl. |
+ size = sizeof(info); |
+ int junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); |
+ ASSERT(junk == 0); |
+ // We're being debugged if the P_TRACED flag is set. |
+ return ((info.kp_proc.p_flag & P_TRACED) != 0); |
+} |
+ |
class ThreadInterrupterMacOS : public AllStatic { |
public: |
static void ThreadInterruptSignalHandler(int signal, |
@@ -48,7 +74,7 @@ class ThreadInterrupterMacOS : public AllStatic { |
void ThreadInterrupter::InterruptThread(OSThread* thread) { |
if (FLAG_trace_thread_interrupter) { |
- OS::Print("ThreadInterrupter interrupting %p\n", thread->id()); |
+ OS::PrintErr("ThreadInterrupter interrupting %p\n", thread->id()); |
} |
int result = pthread_kill(thread->id(), SIGPROF); |
ASSERT((result == 0) || (result == ESRCH)); |