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

Unified Diff: runtime/vm/debugger.cc

Issue 2767483002: Fix two bugs with async stack traces. (Closed)
Patch Set: Created 3 years, 9 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 | « runtime/vm/debugger.h ('k') | runtime/vm/flag_list.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/debugger.cc
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 44b156bd432875d1d93dde3305755bd1c3a948a8..509abb68252285a59f7b4aca4ec791686b041791 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1904,7 +1904,7 @@ DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() {
for (InlinedFunctionsIterator it(code, pc); !it.Done();
it.Advance()) {
inlined_code = it.code();
- stack_trace->AddAsyncCausalFrame(pc, inlined_code);
+ stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
}
} else {
stack_trace->AddAsyncCausalFrame(pc, code);
@@ -1923,6 +1923,9 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
if (!FLAG_causal_async_stacks) {
return NULL;
}
+ // Causal async stacks are not supported in the AOT runtime.
+ ASSERT(!FLAG_precompiled_runtime);
+
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
Isolate* isolate = thread->isolate();
@@ -1939,21 +1942,60 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
frame = iterator.NextFrame()) {
ASSERT(frame->IsValid());
+ if (FLAG_trace_debugger_stacktrace) {
+ OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
+ frame->ToCString());
+ }
if (frame->IsDartFrame()) {
code = frame->LookupDartCode();
- function = code.function();
- if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
- ActivationFrame* activation = CollectDartFrame(
- isolate, frame->pc(), frame, code, Object::null_array(), 0,
- ActivationFrame::kAsyncActivation);
- ASSERT(activation != NULL);
- stack_trace->AddActivation(activation);
- // Grab the awaiter.
- async_activation ^= activation->GetAsyncAwaiter();
- break;
+ if (code.is_optimized()) {
+ deopt_frame = DeoptimizeToArray(thread, frame, code);
+ bool found_async_awaiter = false;
+ for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
+ it.Advance()) {
+ inlined_code = it.code();
+ function = inlined_code.function();
+ if (FLAG_trace_debugger_stacktrace) {
+ ASSERT(!function.IsNull());
+ OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n",
+ function.ToFullyQualifiedCString());
+ }
+ intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
+ if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+ ActivationFrame* activation = CollectDartFrame(
+ isolate, it.pc(), frame, inlined_code, deopt_frame,
+ deopt_frame_offset, ActivationFrame::kAsyncActivation);
+ ASSERT(activation != NULL);
+ stack_trace->AddActivation(activation);
+ // Grab the awaiter.
+ async_activation ^= activation->GetAsyncAwaiter();
+ found_async_awaiter = true;
+ break;
+ } else {
+ stack_trace->AddActivation(
+ CollectDartFrame(isolate, it.pc(), frame, inlined_code,
+ deopt_frame, deopt_frame_offset));
+ }
+ }
+ // Break out of outer loop.
+ if (found_async_awaiter) {
+ break;
+ }
} else {
- AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
- &inlined_code, &deopt_frame);
+ function = code.function();
+ if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+ ActivationFrame* activation = CollectDartFrame(
+ isolate, frame->pc(), frame, code, Object::null_array(), 0,
+ ActivationFrame::kAsyncActivation);
+ ASSERT(activation != NULL);
+ stack_trace->AddActivation(activation);
+ // Grab the awaiter.
+ async_activation ^= activation->GetAsyncAwaiter();
+ break;
+ } else {
+ stack_trace->AddActivation(CollectDartFrame(
+ isolate, frame->pc(), frame, code, Object::null_array(), 0));
+ }
}
}
}
@@ -2076,29 +2118,6 @@ Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const {
}
-bool Debugger::ShouldPauseOnAsyncException(DebuggerStackTrace* stack_trace,
- const Instance& exc) {
- if (exc_pause_info_ == kNoPauseOnExceptions) {
- return false;
- }
- if (exc_pause_info_ == kPauseOnAllExceptions) {
- return true;
- }
- ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions);
- for (intptr_t i = 0; i < stack_trace->Length(); i++) {
- ActivationFrame* frame = stack_trace->FrameAt(i);
- if (frame->HandlesException(exc)) {
- if (FLAG_verbose_debug) {
- OS::PrintErr("%s is caught by frame %s\n", exc.ToCString(),
- frame->ToCString());
- }
- return false;
- }
- }
- return true;
-}
-
-
bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
const Instance& exception) {
if (exc_pause_info_ == kNoPauseOnExceptions) {
@@ -2122,6 +2141,9 @@ bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
void Debugger::PauseException(const Instance& exc) {
+ if (FLAG_stress_async_stacks) {
+ CollectAwaiterReturnStackTrace();
+ }
// We ignore this exception event when the VM is executing code invoked
// by the debugger to evaluate variables values, when we see a nested
// breakpoint or exception event, or if the debugger is not
@@ -2133,7 +2155,7 @@ void Debugger::PauseException(const Instance& exc) {
DebuggerStackTrace* awaiter_stack_trace = CollectAwaiterReturnStackTrace();
DebuggerStackTrace* stack_trace = CollectStackTrace();
if (awaiter_stack_trace != NULL) {
- if (!ShouldPauseOnAsyncException(awaiter_stack_trace, exc)) {
+ if (!ShouldPauseOnException(awaiter_stack_trace, exc)) {
return;
}
} else {
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/flag_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698