Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Unified Diff: runtime/vm/profiler.cc

Issue 1131233005: Use Structured Exception Handler on Windows to gracefully handle guard page faults (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/profiler.cc
===================================================================
--- runtime/vm/profiler.cc (revision 45769)
+++ runtime/vm/profiler.cc (working copy)
@@ -41,7 +41,7 @@
DEFINE_FLAG(bool, profile_vm, true,
"Always collect native stack traces.");
#else
-DEFINE_FLAG(bool, profile_vm, false,
+DEFINE_FLAG(bool, profile_vm, true,
"Always collect native stack traces.");
#endif
@@ -897,17 +897,6 @@
// If FP == SP, the pc marker hasn't been pushed.
if (fp > sp) {
-#if defined(TARGET_OS_WINDOWS)
- COMPILE_ASSERT(kPcMarkerSlotFromFp < 0);
- // If the fp is at the beginning of a page, it may be unsafe to access
- // the pc marker, because we are reading it from a different thread on
- // Windows. The marker is below fp and the previous page may be a guard
- // page.
- const intptr_t kPageMask = VirtualMemory::PageSize() - 1;
- if ((sample->fp() & kPageMask) == 0) {
- return;
- }
-#endif
uword* pc_marker_ptr = fp + kPcMarkerSlotFromFp;
// MSan/ASan are unaware of frames initialized by generated code.
MSAN_UNPOISON(pc_marker_ptr, kWordSize);
@@ -937,6 +926,92 @@
}
+#if defined(TARGET_OS_WINDOWS)
+// On Windows this code is synchronously executed from the thread interrupter
+// thread. This means we can safely have a static fault_address.
+static uword fault_address = 0;
+static LONG GuardPageExceptionFilter(EXCEPTION_POINTERS* ep) {
+ fault_address = 0;
+ if (ep->ExceptionRecord->ExceptionCode != STATUS_GUARD_PAGE_VIOLATION) {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ // https://goo.gl/p5Fe10
+ fault_address = ep->ExceptionRecord->ExceptionInformation[1];
+ // Read access.
+ ASSERT(ep->ExceptionRecord->ExceptionInformation[0] == 0);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+// All memory access done to collect the sample is performed in CollectSample.
+static void CollectSample(Isolate* isolate,
+ bool exited_dart_code,
+ bool in_dart_code,
+ Sample* sample,
+ uword stack_lower,
+ uword stack_upper,
+ uword pc,
+ uword fp,
+ uword sp) {
+#if defined(TARGET_OS_WINDOWS)
+ // Use structured exception handling to trap guard page access on Windows.
+ __try {
+#endif
+
+ CopyStackBuffer(sample);
+ CopyPCMarkerIfSafe(sample);
+
+ if (FLAG_profile_vm) {
+ // Always walk the native stack collecting both native and Dart frames.
+ ProfilerNativeStackWalker stackWalker(sample,
+ stack_lower,
+ stack_upper,
+ pc,
+ fp,
+ sp);
+ stackWalker.walk();
+ } else if (exited_dart_code) {
+ // We have a valid exit frame info, use the Dart stack walker.
+ ProfilerDartExitStackWalker stackWalker(isolate, sample);
+ stackWalker.walk();
+ } else if (in_dart_code) {
+ // We are executing Dart code. We have frame pointers.
+ ProfilerDartStackWalker stackWalker(isolate,
+ sample,
+ stack_lower,
+ stack_upper,
+ pc,
+ fp,
+ sp);
+ stackWalker.walk();
+ } else {
+ sample->set_vm_tag(VMTag::kEmbedderTagId);
+ sample->SetAt(0, pc);
+ }
+
+#if defined(TARGET_OS_WINDOWS)
+ // Use structured exception handling to trap guard page access.
+ } __except(GuardPageExceptionFilter(GetExceptionInformation())) {
+ // Sample collection triggered a guard page fault:
+ // 1) discard entire sample.
+ sample->set_ignore_sample(true);
+
+ // 2) Reenable guard bit on page that triggered the fault.
+ // https://goo.gl/5mCsXW
+ DWORD new_protect = PAGE_READWRITE | PAGE_GUARD;
+ DWORD old_protect = 0;
+ BOOL success = VirtualProtect(reinterpret_cast<void*>(fault_address),
+ sizeof(fault_address),
+ new_protect,
+ &old_protect);
+ USE(success);
+ ASSERT(success);
+ ASSERT(old_protect == PAGE_READWRITE);
+ }
+#endif
+}
+
+
void Profiler::RecordSampleInterruptCallback(
const InterruptedThreadState& state,
void* data) {
@@ -1075,36 +1150,17 @@
sample->set_sp(sp);
sample->set_fp(fp);
sample->set_lr(lr);
- CopyStackBuffer(sample);
- CopyPCMarkerIfSafe(sample);
- if (FLAG_profile_vm) {
- // Always walk the native stack collecting both native and Dart frames.
- ProfilerNativeStackWalker stackWalker(sample,
- stack_lower,
- stack_upper,
- pc,
- fp,
- sp);
- stackWalker.walk();
- } else if (exited_dart_code) {
- // We have a valid exit frame info, use the Dart stack walker.
- ProfilerDartExitStackWalker stackWalker(isolate, sample);
- stackWalker.walk();
- } else if (in_dart_code) {
- // We are executing Dart code. We have frame pointers.
- ProfilerDartStackWalker stackWalker(isolate,
- sample,
- stack_lower,
- stack_upper,
- pc,
- fp,
- sp);
- stackWalker.walk();
- } else {
- sample->set_vm_tag(VMTag::kEmbedderTagId);
- sample->SetAt(0, pc);
- }
+ // All memory access is done inside CollectSample.
+ CollectSample(isolate,
+ exited_dart_code,
+ in_dart_code,
+ sample,
+ stack_lower,
+ stack_upper,
+ pc,
+ fp,
+ sp);
}
} // namespace dart
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698