mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Disable the profiler when a debugger is attached
Fixes #28702 BUG= R=vegorov@google.com Review-Url: https://codereview.chromium.org/2682343002 .
This commit is contained in:
parent
a4c42824ed
commit
95a8166523
7 changed files with 75 additions and 19 deletions
|
@ -70,8 +70,17 @@ void ThreadInterrupter::InitOnce() {
|
|||
|
||||
void ThreadInterrupter::Startup() {
|
||||
ASSERT(initialized_);
|
||||
if (IsDebuggerAttached()) {
|
||||
MonitorLocker shutdown_ml(monitor_);
|
||||
shutdown_ = true;
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::PrintErr(
|
||||
"ThreadInterrupter disabled because a debugger is attached.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter starting up.\n");
|
||||
OS::PrintErr("ThreadInterrupter starting up.\n");
|
||||
}
|
||||
ASSERT(interrupter_thread_id_ == OSThread::kInvalidThreadJoinId);
|
||||
{
|
||||
|
@ -83,7 +92,7 @@ void ThreadInterrupter::Startup() {
|
|||
}
|
||||
ASSERT(interrupter_thread_id_ != OSThread::kInvalidThreadJoinId);
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter running.\n");
|
||||
OS::PrintErr("ThreadInterrupter running.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +109,7 @@ void ThreadInterrupter::Shutdown() {
|
|||
shutdown_ml.Notify();
|
||||
ASSERT(initialized_);
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter shutting down.\n");
|
||||
OS::PrintErr("ThreadInterrupter shutting down.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +119,7 @@ void ThreadInterrupter::Shutdown() {
|
|||
interrupter_thread_id_ = OSThread::kInvalidThreadJoinId;
|
||||
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter shut down.\n");
|
||||
OS::PrintErr("ThreadInterrupter shut down.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +158,7 @@ void ThreadInterrupter::ThreadMain(uword parameters) {
|
|||
ASSERT(initialized_);
|
||||
InstallSignalHandler();
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter thread running.\n");
|
||||
OS::PrintErr("ThreadInterrupter thread running.\n");
|
||||
}
|
||||
{
|
||||
// Signal to main thread we are ready.
|
||||
|
@ -215,7 +224,7 @@ void ThreadInterrupter::ThreadMain(uword parameters) {
|
|||
}
|
||||
RemoveSignalHandler();
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter thread exiting.\n");
|
||||
OS::PrintErr("ThreadInterrupter thread exiting.\n");
|
||||
}
|
||||
{
|
||||
// Signal to main thread we are exiting.
|
||||
|
|
|
@ -48,6 +48,8 @@ class ThreadInterrupter : public AllStatic {
|
|||
static intptr_t interrupt_period_;
|
||||
static intptr_t current_wait_time_;
|
||||
|
||||
static bool IsDebuggerAttached();
|
||||
|
||||
static bool InDeepSleep() {
|
||||
return current_wait_time_ == Monitor::kNoTimeout;
|
||||
}
|
||||
|
|
|
@ -47,10 +47,15 @@ class ThreadInterrupterAndroid : public AllStatic {
|
|||
};
|
||||
|
||||
|
||||
bool ThreadInterrupter::IsDebuggerAttached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ThreadInterrupter::InterruptThread(OSThread* thread) {
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter interrupting %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter interrupting %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
}
|
||||
int result = syscall(__NR_tgkill, getpid(), thread->id(), SIGPROF);
|
||||
ASSERT((result == 0) || (result == ESRCH));
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
bool ThreadInterrupter::IsDebuggerAttached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ThreadInterrupter::InterruptThread(OSThread* thread) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
|
|
@ -44,10 +44,15 @@ class ThreadInterrupterLinux : public AllStatic {
|
|||
};
|
||||
|
||||
|
||||
bool ThreadInterrupter::IsDebuggerAttached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ThreadInterrupter::InterruptThread(OSThread* thread) {
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter interrupting %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter interrupting %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
}
|
||||
int result = pthread_kill(thread->id(), SIGPROF);
|
||||
ASSERT((result == 0) || (result == ESRCH));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -63,8 +63,8 @@ class ThreadInterrupterWin : public AllStatic {
|
|||
DWORD result = SuspendThread(handle);
|
||||
if (result == kThreadError) {
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter failed to suspend thread %p\n",
|
||||
reinterpret_cast<void*>(os_thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter failed to suspend thread %p\n",
|
||||
reinterpret_cast<void*>(os_thread->id()));
|
||||
}
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
|
@ -74,8 +74,8 @@ class ThreadInterrupterWin : public AllStatic {
|
|||
// Failed to get thread registers.
|
||||
ResumeThread(handle);
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter failed to get registers for %p\n",
|
||||
reinterpret_cast<void*>(os_thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter failed to get registers for %p\n",
|
||||
reinterpret_cast<void*>(os_thread->id()));
|
||||
}
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
|
@ -93,15 +93,20 @@ class ThreadInterrupterWin : public AllStatic {
|
|||
};
|
||||
|
||||
|
||||
bool ThreadInterrupter::IsDebuggerAttached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ThreadInterrupter::InterruptThread(OSThread* thread) {
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter suspending %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter suspending %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
}
|
||||
ThreadInterrupterWin::Interrupt(thread);
|
||||
if (FLAG_trace_thread_interrupter) {
|
||||
OS::Print("ThreadInterrupter resuming %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
OS::PrintErr("ThreadInterrupter resuming %p\n",
|
||||
reinterpret_cast<void*>(thread->id()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue