| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "platform/address_sanitizer.h" | 9 #include "platform/address_sanitizer.h" |
| 10 | 10 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 if (ignore_breakpoints_ || IsPaused()) { | 370 if (ignore_breakpoints_ || IsPaused()) { |
| 371 // We don't let the isolate get interrupted if we are already | 371 // We don't let the isolate get interrupted if we are already |
| 372 // paused or ignoring breakpoints. | 372 // paused or ignoring breakpoints. |
| 373 return Error::null(); | 373 return Error::null(); |
| 374 } | 374 } |
| 375 ServiceEvent event(isolate_, kind); | 375 ServiceEvent event(isolate_, kind); |
| 376 DebuggerStackTrace* trace = CollectStackTrace(); | 376 DebuggerStackTrace* trace = CollectStackTrace(); |
| 377 if (trace->Length() > 0) { | 377 if (trace->Length() > 0) { |
| 378 event.set_top_frame(trace->FrameAt(0)); | 378 event.set_top_frame(trace->FrameAt(0)); |
| 379 } | 379 } |
| 380 CacheStackTraces(trace, CollectAsyncCausalStackTrace()); | 380 CacheStackTraces(trace, CollectAsyncCausalStackTrace(), |
| 381 CollectAwaiterReturnStackTrace()); |
| 381 resume_action_ = kContinue; | 382 resume_action_ = kContinue; |
| 382 Pause(&event); | 383 Pause(&event); |
| 383 HandleSteppingRequest(trace); | 384 HandleSteppingRequest(trace); |
| 384 ClearCachedStackTraces(); | 385 ClearCachedStackTraces(); |
| 385 | 386 |
| 386 // If any error occurred while in the debug message loop, return it here. | 387 // If any error occurred while in the debug message loop, return it here. |
| 387 const Error& error = Error::Handle(Thread::Current()->sticky_error()); | 388 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 388 ASSERT(error.IsNull() || error.IsUnwindError()); | 389 ASSERT(error.IsNull() || error.IsUnwindError()); |
| 389 Thread::Current()->clear_sticky_error(); | 390 Thread::Current()->clear_sticky_error(); |
| 390 return error.raw(); | 391 return error.raw(); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 } | 707 } |
| 707 } | 708 } |
| 708 } | 709 } |
| 709 ASSERT(context_level_ >= 0); | 710 ASSERT(context_level_ >= 0); |
| 710 } | 711 } |
| 711 return context_level_; | 712 return context_level_; |
| 712 } | 713 } |
| 713 | 714 |
| 714 | 715 |
| 715 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { | 716 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { |
| 716 if (!function_.IsAsyncClosure()) { | 717 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { |
| 717 return Object::null(); | 718 return Object::null(); |
| 718 } | 719 } |
| 719 GetVarDescriptors(); | 720 GetVarDescriptors(); |
| 720 intptr_t var_desc_len = var_descriptors_.Length(); | 721 intptr_t var_desc_len = var_descriptors_.Length(); |
| 721 for (intptr_t i = 0; i < var_desc_len; i++) { | 722 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 722 RawLocalVarDescriptors::VarInfo var_info; | 723 RawLocalVarDescriptors::VarInfo var_info; |
| 723 var_descriptors_.GetInfo(i, &var_info); | 724 var_descriptors_.GetInfo(i, &var_info); |
| 724 if (var_descriptors_.GetName(i) == name.raw()) { | 725 if (var_descriptors_.GetName(i) == name.raw()) { |
| 725 const int8_t kind = var_info.kind(); | 726 const int8_t kind = var_info.kind(); |
| 726 if (!live_frame_) { | 727 if (!live_frame_) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 const Object& async_stream_controller_stream = | 793 const Object& async_stream_controller_stream = |
| 793 Object::Handle(GetAsyncStreamControllerStream()); | 794 Object::Handle(GetAsyncStreamControllerStream()); |
| 794 if (!async_stream_controller_stream.IsNull()) { | 795 if (!async_stream_controller_stream.IsNull()) { |
| 795 return GetAsyncStreamControllerStreamAwaiter( | 796 return GetAsyncStreamControllerStreamAwaiter( |
| 796 async_stream_controller_stream); | 797 async_stream_controller_stream); |
| 797 } | 798 } |
| 798 return Object::null(); | 799 return Object::null(); |
| 799 } | 800 } |
| 800 | 801 |
| 801 | 802 |
| 803 RawObject* ActivationFrame::GetCausalStack() { |
| 804 return GetAsyncContextVariable(Symbols::AsyncStackTraceVar()); |
| 805 } |
| 806 |
| 807 |
| 802 bool ActivationFrame::HandlesException(const Instance& exc_obj) { | 808 bool ActivationFrame::HandlesException(const Instance& exc_obj) { |
| 803 intptr_t try_index = TryIndex(); | 809 intptr_t try_index = TryIndex(); |
| 804 if (try_index < 0) { | 810 if (try_index < 0) { |
| 805 return false; | 811 return false; |
| 806 } | 812 } |
| 807 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 813 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
| 808 Array& handled_types = Array::Handle(); | 814 Array& handled_types = Array::Handle(); |
| 809 AbstractType& type = Type::Handle(); | 815 AbstractType& type = Type::Handle(); |
| 810 const bool is_async = | 816 const bool is_async = |
| 811 function().IsAsyncClosure() || function().IsAsyncGenClosure(); | 817 function().IsAsyncClosure() || function().IsAsyncGenClosure(); |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 } | 1308 } |
| 1303 | 1309 |
| 1304 | 1310 |
| 1305 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) { | 1311 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) { |
| 1306 if (kind_ == kRegular) { | 1312 if (kind_ == kRegular) { |
| 1307 PrintToJSONObjectRegular(jsobj, full); | 1313 PrintToJSONObjectRegular(jsobj, full); |
| 1308 } else if (kind_ == kAsyncCausal) { | 1314 } else if (kind_ == kAsyncCausal) { |
| 1309 PrintToJSONObjectAsyncCausal(jsobj, full); | 1315 PrintToJSONObjectAsyncCausal(jsobj, full); |
| 1310 } else if (kind_ == kAsyncSuspensionMarker) { | 1316 } else if (kind_ == kAsyncSuspensionMarker) { |
| 1311 PrintToJSONObjectAsyncSuspensionMarker(jsobj, full); | 1317 PrintToJSONObjectAsyncSuspensionMarker(jsobj, full); |
| 1318 } else if (kind_ == kAsyncActivation) { |
| 1319 PrintToJSONObjectAsyncActivation(jsobj, full); |
| 1312 } else { | 1320 } else { |
| 1313 UNIMPLEMENTED(); | 1321 UNIMPLEMENTED(); |
| 1314 } | 1322 } |
| 1315 } | 1323 } |
| 1316 | 1324 |
| 1317 | 1325 |
| 1318 void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) { | 1326 void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) { |
| 1319 const Script& script = Script::Handle(SourceScript()); | 1327 const Script& script = Script::Handle(SourceScript()); |
| 1320 jsobj->AddProperty("type", "Frame"); | 1328 jsobj->AddProperty("type", "Frame"); |
| 1321 jsobj->AddProperty("kind", KindToCString(kind_)); | 1329 jsobj->AddProperty("kind", KindToCString(kind_)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1336 String& var_name = String::Handle(); | 1344 String& var_name = String::Handle(); |
| 1337 Instance& var_value = Instance::Handle(); | 1345 Instance& var_value = Instance::Handle(); |
| 1338 TokenPosition declaration_token_pos; | 1346 TokenPosition declaration_token_pos; |
| 1339 TokenPosition visible_start_token_pos; | 1347 TokenPosition visible_start_token_pos; |
| 1340 TokenPosition visible_end_token_pos; | 1348 TokenPosition visible_end_token_pos; |
| 1341 VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos, | 1349 VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos, |
| 1342 &visible_end_token_pos, &var_value); | 1350 &visible_end_token_pos, &var_value); |
| 1343 if ((var_name.raw() != Symbols::AsyncOperation().raw()) && | 1351 if ((var_name.raw() != Symbols::AsyncOperation().raw()) && |
| 1344 (var_name.raw() != Symbols::AsyncCompleter().raw()) && | 1352 (var_name.raw() != Symbols::AsyncCompleter().raw()) && |
| 1345 (var_name.raw() != Symbols::ControllerStream().raw()) && | 1353 (var_name.raw() != Symbols::ControllerStream().raw()) && |
| 1346 (var_name.raw() != Symbols::AwaitJumpVar().raw())) { | 1354 (var_name.raw() != Symbols::AwaitJumpVar().raw()) && |
| 1355 (var_name.raw() != Symbols::AsyncStackTraceVar().raw())) { |
| 1347 JSONObject jsvar(&jsvars); | 1356 JSONObject jsvar(&jsvars); |
| 1348 jsvar.AddProperty("type", "BoundVariable"); | 1357 jsvar.AddProperty("type", "BoundVariable"); |
| 1349 var_name = String::ScrubName(var_name); | 1358 var_name = String::ScrubName(var_name); |
| 1350 jsvar.AddProperty("name", var_name.ToCString()); | 1359 jsvar.AddProperty("name", var_name.ToCString()); |
| 1351 jsvar.AddProperty("value", var_value, !full); | 1360 jsvar.AddProperty("value", var_value, !full); |
| 1352 // Where was the variable declared? | 1361 // Where was the variable declared? |
| 1353 jsvar.AddProperty("declarationTokenPos", declaration_token_pos); | 1362 jsvar.AddProperty("declarationTokenPos", declaration_token_pos); |
| 1354 // When the variable becomes visible to the scope. | 1363 // When the variable becomes visible to the scope. |
| 1355 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos); | 1364 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos); |
| 1356 // When the variable stops being visible to the scope. | 1365 // When the variable stops being visible to the scope. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1380 | 1389 |
| 1381 | 1390 |
| 1382 void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, | 1391 void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, |
| 1383 bool full) { | 1392 bool full) { |
| 1384 jsobj->AddProperty("type", "Frame"); | 1393 jsobj->AddProperty("type", "Frame"); |
| 1385 jsobj->AddProperty("kind", KindToCString(kind_)); | 1394 jsobj->AddProperty("kind", KindToCString(kind_)); |
| 1386 jsobj->AddProperty("marker", "AsynchronousSuspension"); | 1395 jsobj->AddProperty("marker", "AsynchronousSuspension"); |
| 1387 } | 1396 } |
| 1388 | 1397 |
| 1389 | 1398 |
| 1399 void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj, |
| 1400 bool full) { |
| 1401 jsobj->AddProperty("type", "Frame"); |
| 1402 jsobj->AddProperty("kind", KindToCString(kind_)); |
| 1403 const Script& script = Script::Handle(SourceScript()); |
| 1404 const TokenPosition pos = TokenPos().SourcePosition(); |
| 1405 jsobj->AddLocation(script, pos); |
| 1406 jsobj->AddProperty("function", function(), !full); |
| 1407 jsobj->AddProperty("code", code()); |
| 1408 if (full) { |
| 1409 // TODO(cutch): The old "full" script usage no longer fits |
| 1410 // in the world where we pass the script as part of the |
| 1411 // location. |
| 1412 jsobj->AddProperty("script", script, !full); |
| 1413 } |
| 1414 } |
| 1415 |
| 1416 |
| 1390 static bool IsFunctionVisible(const Function& function) { | 1417 static bool IsFunctionVisible(const Function& function) { |
| 1391 return FLAG_show_invisible_frames || function.is_visible(); | 1418 return FLAG_show_invisible_frames || function.is_visible(); |
| 1392 } | 1419 } |
| 1393 | 1420 |
| 1394 | 1421 |
| 1395 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { | 1422 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { |
| 1396 if (IsFunctionVisible(frame->function())) { | 1423 if (IsFunctionVisible(frame->function())) { |
| 1397 trace_.Add(frame); | 1424 trace_.Add(frame); |
| 1398 } | 1425 } |
| 1399 } | 1426 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 breakpoint_locations_(NULL), | 1560 breakpoint_locations_(NULL), |
| 1534 code_breakpoints_(NULL), | 1561 code_breakpoints_(NULL), |
| 1535 resume_action_(kContinue), | 1562 resume_action_(kContinue), |
| 1536 resume_frame_index_(-1), | 1563 resume_frame_index_(-1), |
| 1537 post_deopt_frame_index_(-1), | 1564 post_deopt_frame_index_(-1), |
| 1538 ignore_breakpoints_(false), | 1565 ignore_breakpoints_(false), |
| 1539 pause_event_(NULL), | 1566 pause_event_(NULL), |
| 1540 obj_cache_(NULL), | 1567 obj_cache_(NULL), |
| 1541 stack_trace_(NULL), | 1568 stack_trace_(NULL), |
| 1542 async_causal_stack_trace_(NULL), | 1569 async_causal_stack_trace_(NULL), |
| 1570 awaiter_stack_trace_(NULL), |
| 1543 stepping_fp_(0), | 1571 stepping_fp_(0), |
| 1544 skip_next_step_(false), | 1572 skip_next_step_(false), |
| 1545 needs_breakpoint_cleanup_(false), | 1573 needs_breakpoint_cleanup_(false), |
| 1546 synthetic_async_breakpoint_(NULL), | 1574 synthetic_async_breakpoint_(NULL), |
| 1547 exc_pause_info_(kNoPauseOnExceptions) {} | 1575 exc_pause_info_(kNoPauseOnExceptions) {} |
| 1548 | 1576 |
| 1549 | 1577 |
| 1550 Debugger::~Debugger() { | 1578 Debugger::~Debugger() { |
| 1551 isolate_id_ = ILLEGAL_ISOLATE_ID; | 1579 isolate_id_ = ILLEGAL_ISOLATE_ID; |
| 1552 ASSERT(!IsPaused()); | 1580 ASSERT(!IsPaused()); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1930 ASSERT(!FLAG_precompiled_runtime); | 1958 ASSERT(!FLAG_precompiled_runtime); |
| 1931 | 1959 |
| 1932 Thread* thread = Thread::Current(); | 1960 Thread* thread = Thread::Current(); |
| 1933 Zone* zone = thread->zone(); | 1961 Zone* zone = thread->zone(); |
| 1934 Isolate* isolate = thread->isolate(); | 1962 Isolate* isolate = thread->isolate(); |
| 1935 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 1963 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 1936 | 1964 |
| 1937 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1965 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1938 | 1966 |
| 1939 Code& code = Code::Handle(zone); | 1967 Code& code = Code::Handle(zone); |
| 1968 Smi& offset = Smi::Handle(zone); |
| 1940 Function& function = Function::Handle(zone); | 1969 Function& function = Function::Handle(zone); |
| 1941 Code& inlined_code = Code::Handle(zone); | 1970 Code& inlined_code = Code::Handle(zone); |
| 1942 Closure& async_activation = Closure::Handle(zone); | 1971 Closure& async_activation = Closure::Handle(zone); |
| 1972 Object& next_async_activation = Object::Handle(zone); |
| 1943 Array& deopt_frame = Array::Handle(zone); | 1973 Array& deopt_frame = Array::Handle(zone); |
| 1974 class StackTrace& async_stack_trace = StackTrace::Handle(zone); |
| 1944 | 1975 |
| 1945 for (StackFrame* frame = iterator.NextFrame(); frame != NULL; | 1976 for (StackFrame* frame = iterator.NextFrame(); frame != NULL; |
| 1946 frame = iterator.NextFrame()) { | 1977 frame = iterator.NextFrame()) { |
| 1947 ASSERT(frame->IsValid()); | 1978 ASSERT(frame->IsValid()); |
| 1948 if (FLAG_trace_debugger_stacktrace) { | 1979 if (FLAG_trace_debugger_stacktrace) { |
| 1949 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", | 1980 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", |
| 1950 frame->ToCString()); | 1981 frame->ToCString()); |
| 1951 } | 1982 } |
| 1952 if (frame->IsDartFrame()) { | 1983 if (frame->IsDartFrame()) { |
| 1953 code = frame->LookupDartCode(); | 1984 code = frame->LookupDartCode(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 } | 2035 } |
| 2005 | 2036 |
| 2006 // Return NULL to indicate that there is no useful information in this stack | 2037 // Return NULL to indicate that there is no useful information in this stack |
| 2007 // trace because we never found an awaiter. | 2038 // trace because we never found an awaiter. |
| 2008 if (async_activation.IsNull()) { | 2039 if (async_activation.IsNull()) { |
| 2009 return NULL; | 2040 return NULL; |
| 2010 } | 2041 } |
| 2011 | 2042 |
| 2012 // Append the awaiter return call stack. | 2043 // Append the awaiter return call stack. |
| 2013 while (!async_activation.IsNull()) { | 2044 while (!async_activation.IsNull()) { |
| 2014 ActivationFrame* activation = new ActivationFrame(async_activation); | 2045 ActivationFrame* activation = new (zone) ActivationFrame(async_activation); |
| 2015 async_activation ^= activation->GetAsyncAwaiter(); | |
| 2016 activation->ExtractTokenPositionFromAsyncClosure(); | 2046 activation->ExtractTokenPositionFromAsyncClosure(); |
| 2017 stack_trace->AddActivation(activation); | 2047 stack_trace->AddActivation(activation); |
| 2048 next_async_activation = activation->GetAsyncAwaiter(); |
| 2049 if (next_async_activation.IsNull()) { |
| 2050 // No more awaiters. Extract the causal stack trace (if it exists). |
| 2051 async_stack_trace ^= activation->GetCausalStack(); |
| 2052 break; |
| 2053 } |
| 2054 async_activation = Closure::RawCast(next_async_activation.raw()); |
| 2055 } |
| 2056 |
| 2057 // Now we append the asynchronous causal stack trace. These are not active |
| 2058 // frames but a historical record of how this asynchronous function was |
| 2059 // activated. |
| 2060 while (!async_stack_trace.IsNull()) { |
| 2061 for (intptr_t i = 0; i < async_stack_trace.Length(); i++) { |
| 2062 if (async_stack_trace.CodeAtFrame(i) == Code::null()) { |
| 2063 // Incomplete OutOfMemory/StackOverflow trace OR array padding. |
| 2064 break; |
| 2065 } |
| 2066 if (async_stack_trace.CodeAtFrame(i) == |
| 2067 StubCode::AsynchronousGapMarker_entry()->code()) { |
| 2068 stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker); |
| 2069 // The frame immediately below the asynchronous gap marker is the |
| 2070 // identical to the frame above the marker. Skip the frame to enhance |
| 2071 // the readability of the trace. |
| 2072 i++; |
| 2073 } else { |
| 2074 code = Code::RawCast(async_stack_trace.CodeAtFrame(i)); |
| 2075 offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i)); |
| 2076 uword pc = code.PayloadStart() + offset.Value(); |
| 2077 if (code.is_optimized()) { |
| 2078 for (InlinedFunctionsIterator it(code, pc); !it.Done(); |
| 2079 it.Advance()) { |
| 2080 inlined_code = it.code(); |
| 2081 stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code); |
| 2082 } |
| 2083 } else { |
| 2084 stack_trace->AddAsyncCausalFrame(pc, code); |
| 2085 } |
| 2086 } |
| 2087 } |
| 2088 // Follow the link. |
| 2089 async_stack_trace = async_stack_trace.async_link(); |
| 2018 } | 2090 } |
| 2019 | 2091 |
| 2020 return stack_trace; | 2092 return stack_trace; |
| 2021 } | 2093 } |
| 2022 | 2094 |
| 2023 | 2095 |
| 2024 ActivationFrame* Debugger::TopDartFrame() const { | 2096 ActivationFrame* Debugger::TopDartFrame() const { |
| 2025 StackFrameIterator iterator(false); | 2097 StackFrameIterator iterator(false); |
| 2026 StackFrame* frame = iterator.NextFrame(); | 2098 StackFrame* frame = iterator.NextFrame(); |
| 2027 while ((frame != NULL) && !frame->IsDartFrame()) { | 2099 while ((frame != NULL) && !frame->IsDartFrame()) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2048 return (async_causal_stack_trace_ != NULL) ? async_causal_stack_trace_ | 2120 return (async_causal_stack_trace_ != NULL) ? async_causal_stack_trace_ |
| 2049 : CollectAsyncCausalStackTrace(); | 2121 : CollectAsyncCausalStackTrace(); |
| 2050 } | 2122 } |
| 2051 | 2123 |
| 2052 | 2124 |
| 2053 DebuggerStackTrace* Debugger::CurrentAsyncCausalStackTrace() { | 2125 DebuggerStackTrace* Debugger::CurrentAsyncCausalStackTrace() { |
| 2054 return CollectAsyncCausalStackTrace(); | 2126 return CollectAsyncCausalStackTrace(); |
| 2055 } | 2127 } |
| 2056 | 2128 |
| 2057 | 2129 |
| 2130 DebuggerStackTrace* Debugger::AwaiterStackTrace() { |
| 2131 return (awaiter_stack_trace_ != NULL) ? awaiter_stack_trace_ |
| 2132 : CollectAwaiterReturnStackTrace(); |
| 2133 } |
| 2134 |
| 2135 |
| 2136 DebuggerStackTrace* Debugger::CurrentAwaiterStackTrace() { |
| 2137 return CollectAwaiterReturnStackTrace(); |
| 2138 } |
| 2139 |
| 2140 |
| 2058 DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) { | 2141 DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) { |
| 2059 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 2142 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 2060 Function& function = Function::Handle(); | 2143 Function& function = Function::Handle(); |
| 2061 Code& code = Code::Handle(); | 2144 Code& code = Code::Handle(); |
| 2062 | 2145 |
| 2063 const uword fp = 0; | 2146 const uword fp = 0; |
| 2064 const uword sp = 0; | 2147 const uword sp = 0; |
| 2065 const Array& deopt_frame = Array::Handle(); | 2148 const Array& deopt_frame = Array::Handle(); |
| 2066 const intptr_t deopt_frame_offset = -1; | 2149 const intptr_t deopt_frame_offset = -1; |
| 2067 | 2150 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 } else { | 2247 } else { |
| 2165 if (!ShouldPauseOnException(stack_trace, exc)) { | 2248 if (!ShouldPauseOnException(stack_trace, exc)) { |
| 2166 return; | 2249 return; |
| 2167 } | 2250 } |
| 2168 } | 2251 } |
| 2169 ServiceEvent event(isolate_, ServiceEvent::kPauseException); | 2252 ServiceEvent event(isolate_, ServiceEvent::kPauseException); |
| 2170 event.set_exception(&exc); | 2253 event.set_exception(&exc); |
| 2171 if (stack_trace->Length() > 0) { | 2254 if (stack_trace->Length() > 0) { |
| 2172 event.set_top_frame(stack_trace->FrameAt(0)); | 2255 event.set_top_frame(stack_trace->FrameAt(0)); |
| 2173 } | 2256 } |
| 2174 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace()); | 2257 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), |
| 2258 CollectAwaiterReturnStackTrace()); |
| 2175 Pause(&event); | 2259 Pause(&event); |
| 2176 HandleSteppingRequest(stack_trace_); // we may get a rewind request | 2260 HandleSteppingRequest(stack_trace_); // we may get a rewind request |
| 2177 ClearCachedStackTraces(); | 2261 ClearCachedStackTraces(); |
| 2178 } | 2262 } |
| 2179 | 2263 |
| 2180 | 2264 |
| 2181 static TokenPosition LastTokenOnLine(Zone* zone, | 2265 static TokenPosition LastTokenOnLine(Zone* zone, |
| 2182 const TokenStream& tokens, | 2266 const TokenStream& tokens, |
| 2183 TokenPosition pos) { | 2267 TokenPosition pos) { |
| 2184 TokenStream::Iterator iter(zone, tokens, pos, | 2268 TokenStream::Iterator iter(zone, tokens, pos, |
| (...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3168 frame = iterator.NextFrame(); | 3252 frame = iterator.NextFrame(); |
| 3169 } | 3253 } |
| 3170 } | 3254 } |
| 3171 RewindToFrame(resume_frame_index_); | 3255 RewindToFrame(resume_frame_index_); |
| 3172 UNREACHABLE(); | 3256 UNREACHABLE(); |
| 3173 } | 3257 } |
| 3174 } | 3258 } |
| 3175 | 3259 |
| 3176 | 3260 |
| 3177 void Debugger::CacheStackTraces(DebuggerStackTrace* stack_trace, | 3261 void Debugger::CacheStackTraces(DebuggerStackTrace* stack_trace, |
| 3178 DebuggerStackTrace* async_causal_stack_trace) { | 3262 DebuggerStackTrace* async_causal_stack_trace, |
| 3263 DebuggerStackTrace* awaiter_stack_trace) { |
| 3179 ASSERT(stack_trace_ == NULL); | 3264 ASSERT(stack_trace_ == NULL); |
| 3180 stack_trace_ = stack_trace; | 3265 stack_trace_ = stack_trace; |
| 3181 ASSERT(async_causal_stack_trace_ == NULL); | 3266 ASSERT(async_causal_stack_trace_ == NULL); |
| 3182 async_causal_stack_trace_ = async_causal_stack_trace; | 3267 async_causal_stack_trace_ = async_causal_stack_trace; |
| 3268 ASSERT(awaiter_stack_trace_ == NULL); |
| 3269 awaiter_stack_trace_ = awaiter_stack_trace; |
| 3183 } | 3270 } |
| 3184 | 3271 |
| 3185 | 3272 |
| 3186 void Debugger::ClearCachedStackTraces() { | 3273 void Debugger::ClearCachedStackTraces() { |
| 3187 stack_trace_ = NULL; | 3274 stack_trace_ = NULL; |
| 3188 async_causal_stack_trace_ = NULL; | 3275 async_causal_stack_trace_ = NULL; |
| 3276 awaiter_stack_trace_ = NULL; |
| 3189 } | 3277 } |
| 3190 | 3278 |
| 3191 | 3279 |
| 3192 static intptr_t FindNextRewindFrameIndex(DebuggerStackTrace* stack, | 3280 static intptr_t FindNextRewindFrameIndex(DebuggerStackTrace* stack, |
| 3193 intptr_t frame_index) { | 3281 intptr_t frame_index) { |
| 3194 for (intptr_t i = frame_index + 1; i < stack->Length(); i++) { | 3282 for (intptr_t i = frame_index + 1; i < stack->Length(); i++) { |
| 3195 ActivationFrame* frame = stack->FrameAt(i); | 3283 ActivationFrame* frame = stack->FrameAt(i); |
| 3196 if (frame->IsRewindable()) { | 3284 if (frame->IsRewindable()) { |
| 3197 return i; | 3285 return i; |
| 3198 } | 3286 } |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3519 | 3607 |
| 3520 if (FLAG_verbose_debug) { | 3608 if (FLAG_verbose_debug) { |
| 3521 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", | 3609 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", |
| 3522 String::Handle(frame->SourceUrl()).ToCString(), | 3610 String::Handle(frame->SourceUrl()).ToCString(), |
| 3523 frame->LineNumber(), | 3611 frame->LineNumber(), |
| 3524 String::Handle(frame->QualifiedFunctionName()).ToCString(), | 3612 String::Handle(frame->QualifiedFunctionName()).ToCString(), |
| 3525 frame->TokenPos().ToCString()); | 3613 frame->TokenPos().ToCString()); |
| 3526 } | 3614 } |
| 3527 | 3615 |
| 3528 | 3616 |
| 3529 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace()); | 3617 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(), |
| 3618 CollectAwaiterReturnStackTrace()); |
| 3530 // If this step callback is part of stepping over an await statement, | 3619 // If this step callback is part of stepping over an await statement, |
| 3531 // we saved the synthetic async breakpoint in PauseBreakpoint. We report | 3620 // we saved the synthetic async breakpoint in PauseBreakpoint. We report |
| 3532 // that we are paused at that breakpoint and then delete it after continuing. | 3621 // that we are paused at that breakpoint and then delete it after continuing. |
| 3533 SignalPausedEvent(frame, synthetic_async_breakpoint_); | 3622 SignalPausedEvent(frame, synthetic_async_breakpoint_); |
| 3534 if (synthetic_async_breakpoint_ != NULL) { | 3623 if (synthetic_async_breakpoint_ != NULL) { |
| 3535 RemoveBreakpoint(synthetic_async_breakpoint_->id()); | 3624 RemoveBreakpoint(synthetic_async_breakpoint_->id()); |
| 3536 synthetic_async_breakpoint_ = NULL; | 3625 synthetic_async_breakpoint_ = NULL; |
| 3537 } | 3626 } |
| 3538 HandleSteppingRequest(stack_trace_); | 3627 HandleSteppingRequest(stack_trace_); |
| 3539 ClearCachedStackTraces(); | 3628 ClearCachedStackTraces(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3560 ASSERT(cbpt != NULL); | 3649 ASSERT(cbpt != NULL); |
| 3561 | 3650 |
| 3562 Breakpoint* bpt_hit = FindHitBreakpoint(cbpt->bpt_location_, top_frame); | 3651 Breakpoint* bpt_hit = FindHitBreakpoint(cbpt->bpt_location_, top_frame); |
| 3563 if (bpt_hit == NULL) { | 3652 if (bpt_hit == NULL) { |
| 3564 return Error::null(); | 3653 return Error::null(); |
| 3565 } | 3654 } |
| 3566 | 3655 |
| 3567 if (bpt_hit->is_synthetic_async()) { | 3656 if (bpt_hit->is_synthetic_async()) { |
| 3568 DebuggerStackTrace* stack_trace = CollectStackTrace(); | 3657 DebuggerStackTrace* stack_trace = CollectStackTrace(); |
| 3569 ASSERT(stack_trace->Length() > 0); | 3658 ASSERT(stack_trace->Length() > 0); |
| 3570 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace()); | 3659 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), |
| 3660 CollectAwaiterReturnStackTrace()); |
| 3571 | 3661 |
| 3572 // Hit a synthetic async breakpoint. | 3662 // Hit a synthetic async breakpoint. |
| 3573 if (FLAG_verbose_debug) { | 3663 if (FLAG_verbose_debug) { |
| 3574 OS::Print(">>> hit synthetic breakpoint at %s:%" Pd | 3664 OS::Print(">>> hit synthetic breakpoint at %s:%" Pd |
| 3575 " " | 3665 " " |
| 3576 "(token %s) (address %#" Px ")\n", | 3666 "(token %s) (address %#" Px ")\n", |
| 3577 String::Handle(cbpt->SourceUrl()).ToCString(), | 3667 String::Handle(cbpt->SourceUrl()).ToCString(), |
| 3578 cbpt->LineNumber(), cbpt->token_pos().ToCString(), | 3668 cbpt->LineNumber(), cbpt->token_pos().ToCString(), |
| 3579 top_frame->pc()); | 3669 top_frame->pc()); |
| 3580 } | 3670 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3595 | 3685 |
| 3596 if (FLAG_verbose_debug) { | 3686 if (FLAG_verbose_debug) { |
| 3597 OS::Print(">>> hit breakpoint %" Pd " at %s:%" Pd | 3687 OS::Print(">>> hit breakpoint %" Pd " at %s:%" Pd |
| 3598 " (token %s) " | 3688 " (token %s) " |
| 3599 "(address %#" Px ")\n", | 3689 "(address %#" Px ")\n", |
| 3600 bpt_hit->id(), String::Handle(cbpt->SourceUrl()).ToCString(), | 3690 bpt_hit->id(), String::Handle(cbpt->SourceUrl()).ToCString(), |
| 3601 cbpt->LineNumber(), cbpt->token_pos().ToCString(), | 3691 cbpt->LineNumber(), cbpt->token_pos().ToCString(), |
| 3602 top_frame->pc()); | 3692 top_frame->pc()); |
| 3603 } | 3693 } |
| 3604 | 3694 |
| 3605 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace()); | 3695 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), |
| 3696 CollectAwaiterReturnStackTrace()); |
| 3606 SignalPausedEvent(top_frame, bpt_hit); | 3697 SignalPausedEvent(top_frame, bpt_hit); |
| 3607 // When we single step from a user breakpoint, our next stepping | 3698 // When we single step from a user breakpoint, our next stepping |
| 3608 // point will be at the exact same pc. Skip it. | 3699 // point will be at the exact same pc. Skip it. |
| 3609 HandleSteppingRequest(stack_trace_, true /* skip next step */); | 3700 HandleSteppingRequest(stack_trace_, true /* skip next step */); |
| 3610 ClearCachedStackTraces(); | 3701 ClearCachedStackTraces(); |
| 3611 | 3702 |
| 3612 // If any error occurred while in the debug message loop, return it here. | 3703 // If any error occurred while in the debug message loop, return it here. |
| 3613 const Error& error = Error::Handle(Thread::Current()->sticky_error()); | 3704 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 3614 Thread::Current()->clear_sticky_error(); | 3705 Thread::Current()->clear_sticky_error(); |
| 3615 return error.raw(); | 3706 return error.raw(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3664 void Debugger::PauseDeveloper(const String& msg) { | 3755 void Debugger::PauseDeveloper(const String& msg) { |
| 3665 // We ignore this breakpoint when the VM is executing code invoked | 3756 // We ignore this breakpoint when the VM is executing code invoked |
| 3666 // by the debugger to evaluate variables values, or when we see a nested | 3757 // by the debugger to evaluate variables values, or when we see a nested |
| 3667 // breakpoint or exception event. | 3758 // breakpoint or exception event. |
| 3668 if (ignore_breakpoints_ || IsPaused()) { | 3759 if (ignore_breakpoints_ || IsPaused()) { |
| 3669 return; | 3760 return; |
| 3670 } | 3761 } |
| 3671 | 3762 |
| 3672 DebuggerStackTrace* stack_trace = CollectStackTrace(); | 3763 DebuggerStackTrace* stack_trace = CollectStackTrace(); |
| 3673 ASSERT(stack_trace->Length() > 0); | 3764 ASSERT(stack_trace->Length() > 0); |
| 3674 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace()); | 3765 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), |
| 3766 CollectAwaiterReturnStackTrace()); |
| 3675 // TODO(johnmccutchan): Send |msg| to Observatory. | 3767 // TODO(johnmccutchan): Send |msg| to Observatory. |
| 3676 | 3768 |
| 3677 // We are in the native call to Developer_debugger. the developer | 3769 // We are in the native call to Developer_debugger. the developer |
| 3678 // gets a better experience by not seeing this call. To accomplish | 3770 // gets a better experience by not seeing this call. To accomplish |
| 3679 // this, we continue execution until the call exits (step out). | 3771 // this, we continue execution until the call exits (step out). |
| 3680 SetResumeAction(kStepOut); | 3772 SetResumeAction(kStepOut); |
| 3681 HandleSteppingRequest(stack_trace_); | 3773 HandleSteppingRequest(stack_trace_); |
| 3682 ClearCachedStackTraces(); | 3774 ClearCachedStackTraces(); |
| 3683 } | 3775 } |
| 3684 | 3776 |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 | 4245 |
| 4154 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 4246 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 4155 ASSERT(bpt->next() == NULL); | 4247 ASSERT(bpt->next() == NULL); |
| 4156 bpt->set_next(code_breakpoints_); | 4248 bpt->set_next(code_breakpoints_); |
| 4157 code_breakpoints_ = bpt; | 4249 code_breakpoints_ = bpt; |
| 4158 } | 4250 } |
| 4159 | 4251 |
| 4160 #endif // !PRODUCT | 4252 #endif // !PRODUCT |
| 4161 | 4253 |
| 4162 } // namespace dart | 4254 } // namespace dart |
| OLD | NEW |