Flutter Engine
The Flutter Engine
thread_interrupter_win.cc
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_WINDOWS)
7
8#include "vm/flags.h"
9#include "vm/os.h"
10#include "vm/profiler.h"
12
13namespace dart {
14
15#ifndef PRODUCT
16
17DECLARE_FLAG(bool, trace_thread_interrupter);
18
19#define kThreadError -1
20
21class ThreadInterrupterWin : public AllStatic {
22 public:
23 static bool GrabRegisters(HANDLE handle, InterruptedThreadState* state) {
24 CONTEXT context;
25 memset(&context, 0, sizeof(context));
26#if defined(HOST_ARCH_IA32)
27 // On IA32, CONTEXT_CONTROL includes Eip, Ebp, and Esp.
28 context.ContextFlags = CONTEXT_CONTROL;
29#elif defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM) || \
30 defined(HOST_ARCH_ARM64)
31 // On X64, CONTEXT_CONTROL includes Rip and Rsp. Rbp is classified
32 // as an "integer" register.
33 context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
34#else
35#error Unsupported architecture.
36#endif
37 if (GetThreadContext(handle, &context) != 0) {
38#if defined(HOST_ARCH_IA32)
39 state->pc = static_cast<uintptr_t>(context.Eip);
40 state->fp = static_cast<uintptr_t>(context.Ebp);
41 state->csp = static_cast<uintptr_t>(context.Esp);
42 state->dsp = static_cast<uintptr_t>(context.Esp);
43 state->lr = 0;
44#elif defined(HOST_ARCH_X64)
45 state->pc = static_cast<uintptr_t>(context.Rip);
46 state->fp = static_cast<uintptr_t>(context.Rbp);
47 state->csp = static_cast<uintptr_t>(context.Rsp);
48 state->dsp = static_cast<uintptr_t>(context.Rsp);
49 state->lr = 0;
50#elif defined(HOST_ARCH_ARM)
51 state->pc = static_cast<uintptr_t>(context.Pc);
52 state->fp = static_cast<uintptr_t>(context.R11);
53 state->csp = static_cast<uintptr_t>(context.Sp);
54 state->dsp = static_cast<uintptr_t>(context.Sp);
55 state->lr = static_cast<uintptr_t>(context.R14);
56#elif defined(HOST_ARCH_ARM64)
57 state->pc = static_cast<uintptr_t>(context.Pc);
58 state->fp = static_cast<uintptr_t>(context.Fp);
59 state->csp = static_cast<uintptr_t>(context.Sp);
60 state->dsp = static_cast<uintptr_t>(context.X15);
61 state->lr = static_cast<uintptr_t>(context.Lr);
62#else
63#error Unsupported architecture.
64#endif
65 return true;
66 }
67 return false;
68 }
69
70 static void Interrupt(OSThread* os_thread) {
71 ASSERT(!OSThread::Compare(GetCurrentThreadId(), os_thread->id()));
72 HANDLE handle = OpenThread(
73 THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME,
74 false, os_thread->id());
75 ASSERT(handle != nullptr);
76 DWORD result = SuspendThread(handle);
77 if (result == kThreadError) {
78 if (FLAG_trace_thread_interrupter) {
79 OS::PrintErr("ThreadInterrupter failed to suspend thread %p\n",
80 reinterpret_cast<void*>(os_thread->id()));
81 }
82 CloseHandle(handle);
83 return;
84 }
85 InterruptedThreadState its;
86 if (!GrabRegisters(handle, &its)) {
87 // Failed to get thread registers.
88 ResumeThread(handle);
89 if (FLAG_trace_thread_interrupter) {
90 OS::PrintErr("ThreadInterrupter failed to get registers for %p\n",
91 reinterpret_cast<void*>(os_thread->id()));
92 }
93 CloseHandle(handle);
94 return;
95 }
96 // Currently we sample only threads that are associated
97 // with an isolate. It is safe to call 'os_thread->thread()'
98 // here as the thread which is being queried is suspended.
99 Thread* thread = static_cast<Thread*>(os_thread->thread());
100 if (thread != nullptr) {
101 ThreadInterruptScope signal_handler_scope;
102 Profiler::SampleThread(thread, its);
103 }
104 ResumeThread(handle);
105 CloseHandle(handle);
106 }
107};
108
109void ThreadInterrupter::InterruptThread(OSThread* thread) {
110 if (FLAG_trace_thread_interrupter) {
111 OS::PrintErr("ThreadInterrupter suspending %p\n",
112 reinterpret_cast<void*>(thread->id()));
113 }
114 ThreadInterrupterWin::Interrupt(thread);
115 if (FLAG_trace_thread_interrupter) {
116 OS::PrintErr("ThreadInterrupter resuming %p\n",
117 reinterpret_cast<void*>(thread->id()));
118 }
119}
120
121void ThreadInterrupter::InstallSignalHandler() {
122 // Nothing to do on Windows.
123}
124
125void ThreadInterrupter::RemoveSignalHandler() {
126 // Nothing to do on Windows.
127}
128
129#endif // !PRODUCT
130
131} // namespace dart
132
133#endif // defined(DART_HOST_OS_WINDOWS)
static bool Compare(ThreadId a, ThreadId b)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void SampleThread(Thread *thread, const InterruptedThreadState &state)
Definition: profiler.cc:1354
static void InterruptThread(OSThread *thread)
#define ASSERT(E)
AtkStateType state
GAsyncResult * result
Definition: dart_vm.cc:33
DECLARE_FLAG(bool, show_invisible_frames)
void * HANDLE
Definition: windows_types.h:36
unsigned long DWORD
Definition: windows_types.h:22