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

Side by Side Diff: runtime/vm/debugger.cc

Issue 2692803006: Track the 'awaiter return' call stack use it to detect uncaught exceptions in async functions (Closed)
Patch Set: port to other architectures 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 unified diff | Download patch
OLDNEW
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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 column_number_(-1), 290 column_number_(-1),
291 context_level_(-1), 291 context_level_(-1),
292 deopt_frame_(Array::ZoneHandle()), 292 deopt_frame_(Array::ZoneHandle()),
293 deopt_frame_offset_(0), 293 deopt_frame_offset_(0),
294 kind_(kind), 294 kind_(kind),
295 vars_initialized_(false), 295 vars_initialized_(false),
296 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 296 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
297 desc_indices_(8), 297 desc_indices_(8),
298 pc_desc_(PcDescriptors::ZoneHandle()) {} 298 pc_desc_(PcDescriptors::ZoneHandle()) {}
299 299
300
301 ActivationFrame::ActivationFrame(const Closure& async_activation)
302 : pc_(0),
303 fp_(0),
304 sp_(0),
305 ctx_(Context::ZoneHandle()),
306 code_(Code::ZoneHandle()),
307 function_(Function::ZoneHandle()),
308 live_frame_(false),
309 token_pos_initialized_(false),
310 token_pos_(TokenPosition::kNoSource),
311 try_index_(-1),
312 line_number_(-1),
313 column_number_(-1),
314 context_level_(-1),
315 deopt_frame_(Array::ZoneHandle()),
316 deopt_frame_offset_(0),
317 kind_(kAsyncActivation),
318 vars_initialized_(false),
319 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
320 desc_indices_(8),
321 pc_desc_(PcDescriptors::ZoneHandle()) {
322 // Extract the function and the code from the asynchronous activation.
323 function_ = async_activation.function();
324 code_ = function_.unoptimized_code();
325 ctx_ = async_activation.context();
326 }
327
328
300 bool Debugger::NeedsIsolateEvents() { 329 bool Debugger::NeedsIsolateEvents() {
301 return ((isolate_ != Dart::vm_isolate()) && 330 return ((isolate_ != Dart::vm_isolate()) &&
302 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) && 331 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
303 ((event_handler_ != NULL) || Service::isolate_stream.enabled())); 332 ((event_handler_ != NULL) || Service::isolate_stream.enabled()));
304 } 333 }
305 334
306 335
307 bool Debugger::NeedsDebugEvents() { 336 bool Debugger::NeedsDebugEvents() {
308 ASSERT(isolate_ != Dart::vm_isolate() && 337 ASSERT(isolate_ != Dart::vm_isolate() &&
309 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)); 338 !ServiceIsolate::IsServiceIsolateDescendant(isolate_));
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 innermost_begin_pos = var_info.begin_pos; 701 innermost_begin_pos = var_info.begin_pos;
673 context_level_ = var_info.index(); 702 context_level_ = var_info.index();
674 } 703 }
675 } 704 }
676 } 705 }
677 ASSERT(context_level_ >= 0); 706 ASSERT(context_level_ >= 0);
678 } 707 }
679 return context_level_; 708 return context_level_;
680 } 709 }
681 710
711 RawObject* ActivationFrame::GetAsyncCompleter() {
712 if (!function_.IsAsyncClosure()) {
713 return Object::null();
714 }
715 GetVarDescriptors();
716 intptr_t var_desc_len = var_descriptors_.Length();
717 if (fp() == 0) {
rmacnak 2017/02/23 17:50:56 if (!live_frame) { ... } else { ASSERT(fp != 0
Cutch 2017/02/24 20:19:21 Done.
718 // Not actually on the stack. Pull it out of the closure's context.
719 intptr_t var_desc_len = var_descriptors_.Length();
720 for (intptr_t i = 0; i < var_desc_len; i++) {
721 RawLocalVarDescriptors::VarInfo var_info;
722 var_descriptors_.GetInfo(i, &var_info);
723 const int8_t kind = var_info.kind();
724 if (var_descriptors_.GetName(i) == Symbols::AsyncCompleter().raw()) {
725 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
726 ASSERT(!ctx_.IsNull());
727 return ctx_.At(var_info.index());
728 }
729 }
730 } else {
731 // On the stack.
732 for (intptr_t i = 0; i < var_desc_len; i++) {
733 RawLocalVarDescriptors::VarInfo var_info;
734 var_descriptors_.GetInfo(i, &var_info);
735 if (var_descriptors_.GetName(i) == Symbols::AsyncCompleter().raw()) {
736 const int8_t kind = var_info.kind();
737 if (kind == RawLocalVarDescriptors::kStackVar) {
738 return GetStackVar(var_info.index());
739 } else {
740 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
741 return GetContextVar(var_info.scope_id, var_info.index());
742 }
743 }
744 }
745 }
746 return Object::null();
747 }
748
749
750 RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
751 const Class& sync_completer_cls = Class::Handle(completer.clazz());
752 ASSERT(!sync_completer_cls.IsNull());
753 const Class& completer_cls = Class::Handle(sync_completer_cls.SuperClass());
754 const Field& future_field =
755 Field::Handle(completer_cls.LookupInstanceFieldAllowPrivate(
756 Symbols::CompleterFuture()));
757 ASSERT(!future_field.IsNull());
758 Instance& future = Instance::Handle();
759 future ^= Instance::Cast(completer).GetField(future_field);
760 ASSERT(!future.IsNull());
761 const Class& future_cls = Class::Handle(future.clazz());
762 ASSERT(!future_cls.IsNull());
763 const Field& awaiter_field = Field::Handle(
764 future_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
765 ASSERT(!awaiter_field.IsNull());
766 return future.GetField(awaiter_field);
767 }
768
769
770 RawObject* ActivationFrame::GetAsyncStreamControllerStream() {
771 if (!function_.IsAsyncGenClosure()) {
772 return Object::null();
773 }
774 GetVarDescriptors();
775 intptr_t var_desc_len = var_descriptors_.Length();
776 if (fp() == 0) {
rmacnak 2017/02/23 17:50:56 live_frame
Cutch 2017/02/24 20:19:21 Done.
777 // Not actually on the stack. Pull it out of the closure's context.
778 intptr_t var_desc_len = var_descriptors_.Length();
779 for (intptr_t i = 0; i < var_desc_len; i++) {
780 RawLocalVarDescriptors::VarInfo var_info;
781 var_descriptors_.GetInfo(i, &var_info);
782 const int8_t kind = var_info.kind();
783 if (var_descriptors_.GetName(i) == Symbols::ControllerStream().raw()) {
784 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
785 ASSERT(!ctx_.IsNull());
786 return ctx_.At(var_info.index());
787 }
788 }
789 } else {
790 // On the stack.
791 for (intptr_t i = 0; i < var_desc_len; i++) {
792 RawLocalVarDescriptors::VarInfo var_info;
793 var_descriptors_.GetInfo(i, &var_info);
794 if (var_descriptors_.GetName(i) == Symbols::ControllerStream().raw()) {
795 const int8_t kind = var_info.kind();
796 if (kind == RawLocalVarDescriptors::kStackVar) {
797 return GetStackVar(var_info.index());
798 } else {
799 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
800 return GetContextVar(var_info.scope_id, var_info.index());
801 }
802 }
803 }
804 }
805 return Object::null();
806 }
807
808
809 RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
810 const Object& stream) {
811 const Class& stream_cls = Class::Handle(stream.clazz());
812 ASSERT(!stream_cls.IsNull());
813 const Class& stream_impl_cls = Class::Handle(stream_cls.SuperClass());
814 const Field& awaiter_field = Field::Handle(
815 stream_impl_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
816 ASSERT(!awaiter_field.IsNull());
817 return Instance::Cast(stream).GetField(awaiter_field);
818 }
819
820
821 RawObject* ActivationFrame::GetAsyncAwaiter() {
822 const Object& completer = Object::Handle(GetAsyncCompleter());
823 if (!completer.IsNull()) {
824 return GetAsyncCompleterAwaiter(completer);
825 }
826 const Object& async_stream_controller_stream =
827 Object::Handle(GetAsyncStreamControllerStream());
828 if (!async_stream_controller_stream.IsNull()) {
829 return GetAsyncStreamControllerStreamAwaiter(
830 async_stream_controller_stream);
831 }
832 return Object::null();
833 }
834
835
836 bool ActivationFrame::HandlesException(const Instance& exc_obj) {
rmacnak 2017/02/23 17:50:56 How much slower is ParserCombinators with the debu
837 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
rmacnak 2017/02/23 17:50:56 Move handle creation below the fast exit.
Cutch 2017/02/24 20:19:21 Done.
838 Array& handled_types = Array::Handle();
839 AbstractType& type = Type::Handle();
840 const TypeArguments& no_instantiator = TypeArguments::Handle();
841 intptr_t try_index = TryIndex();
842 if (try_index < 0) {
843 return false;
844 }
845 const intptr_t try_index_threshold = CatchClauseNode::kImplicitAsyncTryIndex;
846 const bool is_async =
847 function().IsAsyncClosure() || function().IsAsyncGenClosure();
848 handlers = code().exception_handlers();
849 ASSERT(!handlers.IsNull());
850 intptr_t num_handlers_checked = 0;
851 while (try_index >= try_index_threshold) {
852 // Detect circles in the exception handler data.
853 num_handlers_checked++;
854 ASSERT(num_handlers_checked <= handlers.num_entries());
855 // Only consider user written handlers for async methods.
856 if (!is_async || !handlers.IsGenerated(try_index)) {
857 handled_types = handlers.GetHandledTypes(try_index);
858 const intptr_t num_types = handled_types.Length();
859 for (intptr_t k = 0; k < num_types; k++) {
860 type ^= handled_types.At(k);
861 ASSERT(!type.IsNull());
862 // Uninstantiated types are not added to ExceptionHandlers data.
863 ASSERT(type.IsInstantiated());
864 if (type.IsMalformed()) {
865 continue;
866 }
867 if (type.IsDynamicType()) {
868 return true;
869 }
870 if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
871 return true;
872 }
873 }
874 }
875 try_index = handlers.OuterTryIndex(try_index);
876 }
877 return false;
878 }
879
880
881 void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
882 // Attempt to determine the token position from the async closure.
883 ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
884 // This should only be called on frames that aren't active on the stack.
885 ASSERT(fp() == 0);
886 const Array& await_to_token_map =
887 Array::Handle(code_.await_token_positions());
888 if (await_to_token_map.IsNull()) {
889 // No mapping.
890 return;
891 }
892 GetVarDescriptors();
893 GetPcDescriptors();
894 intptr_t var_desc_len = var_descriptors_.Length();
895 intptr_t await_jump_var = -1;
896 for (intptr_t i = 0; i < var_desc_len; i++) {
897 RawLocalVarDescriptors::VarInfo var_info;
898 var_descriptors_.GetInfo(i, &var_info);
899 const int8_t kind = var_info.kind();
900 if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) {
901 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
902 ASSERT(!ctx_.IsNull());
903 Object& await_jump_index = Object::Handle(ctx_.At(var_info.index()));
904 ASSERT(await_jump_index.IsSmi());
905 await_jump_var = Smi::Cast(await_jump_index).Value();
906 }
907 }
908 if (await_jump_var < 0) {
909 return;
910 }
911 ASSERT(await_jump_var < await_to_token_map.Length());
912 const Object& token_pos =
913 Object::Handle(await_to_token_map.At(await_jump_var));
914 if (token_pos.IsNull()) {
915 return;
916 }
917 ASSERT(token_pos.IsSmi());
918 token_pos_ = TokenPosition(Smi::Cast(token_pos).Value());
919 token_pos_initialized_ = true;
920 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
921 while (iter.MoveNext()) {
922 if (iter.TokenPos() == token_pos_) {
923 // Match the lowest try index at this token position.
924 // TODO(johnmccutchan): Is this heuristic precise enough?
925 if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) {
926 if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) {
927 try_index_ = iter.TryIndex();
928 }
929 }
930 }
931 }
932 }
933
682 934
683 // Get the saved current context of this activation. 935 // Get the saved current context of this activation.
684 const Context& ActivationFrame::GetSavedCurrentContext() { 936 const Context& ActivationFrame::GetSavedCurrentContext() {
685 if (!ctx_.IsNull()) return ctx_; 937 if (!ctx_.IsNull()) return ctx_;
686 GetVarDescriptors(); 938 GetVarDescriptors();
687 intptr_t var_desc_len = var_descriptors_.Length(); 939 intptr_t var_desc_len = var_descriptors_.Length();
688 for (intptr_t i = 0; i < var_desc_len; i++) { 940 for (intptr_t i = 0; i < var_desc_len; i++) {
689 RawLocalVarDescriptors::VarInfo var_info; 941 RawLocalVarDescriptors::VarInfo var_info;
690 var_descriptors_.GetInfo(i, &var_info); 942 var_descriptors_.GetInfo(i, &var_info);
691 const int8_t kind = var_info.kind(); 943 const int8_t kind = var_info.kind();
(...skipping 25 matching lines...) Expand all
717 return GetContextVar(var_info.scope_id, var_info.index()); 969 return GetContextVar(var_info.scope_id, var_info.index());
718 } 970 }
719 } 971 }
720 } 972 }
721 return Object::null(); 973 return Object::null();
722 } 974 }
723 975
724 976
725 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 977 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
726 const Instance& exc_obj) const { 978 const Instance& exc_obj) const {
727 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
728 Array& handled_types = Array::Handle();
729 AbstractType& type = Type::Handle();
730 const TypeArguments& no_instantiator = TypeArguments::Handle();
731 for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) { 979 for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) {
732 ActivationFrame* frame = FrameAt(frame_index); 980 ActivationFrame* frame = FrameAt(frame_index);
733 intptr_t try_index = frame->TryIndex(); 981 if (frame->HandlesException(exc_obj)) {
734 if (try_index < 0) continue; 982 return frame;
735 handlers = frame->code().exception_handlers();
736 ASSERT(!handlers.IsNull());
737 intptr_t num_handlers_checked = 0;
738 while (try_index >= 0) {
739 // Detect circles in the exception handler data.
740 num_handlers_checked++;
741 ASSERT(num_handlers_checked <= handlers.num_entries());
742 handled_types = handlers.GetHandledTypes(try_index);
743 const intptr_t num_types = handled_types.Length();
744 for (intptr_t k = 0; k < num_types; k++) {
745 type ^= handled_types.At(k);
746 ASSERT(!type.IsNull());
747 // Uninstantiated types are not added to ExceptionHandlers data.
748 ASSERT(type.IsInstantiated());
749 if (type.IsMalformed()) continue;
750 if (type.IsDynamicType()) return frame;
751 if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
752 return frame;
753 }
754 }
755 try_index = handlers.OuterTryIndex(try_index);
756 } 983 }
757 } 984 }
758 return NULL; 985 return NULL;
759 } 986 }
760 987
761 988
762 void ActivationFrame::GetDescIndices() { 989 void ActivationFrame::GetDescIndices() {
763 if (vars_initialized_) { 990 if (vars_initialized_) {
764 return; 991 return;
765 } 992 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 JSONArray jsvars(jsobj, "vars"); 1372 JSONArray jsvars(jsobj, "vars");
1146 const int num_vars = NumLocalVariables(); 1373 const int num_vars = NumLocalVariables();
1147 for (intptr_t v = 0; v < num_vars; v++) { 1374 for (intptr_t v = 0; v < num_vars; v++) {
1148 String& var_name = String::Handle(); 1375 String& var_name = String::Handle();
1149 Instance& var_value = Instance::Handle(); 1376 Instance& var_value = Instance::Handle();
1150 TokenPosition declaration_token_pos; 1377 TokenPosition declaration_token_pos;
1151 TokenPosition visible_start_token_pos; 1378 TokenPosition visible_start_token_pos;
1152 TokenPosition visible_end_token_pos; 1379 TokenPosition visible_end_token_pos;
1153 VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos, 1380 VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos,
1154 &visible_end_token_pos, &var_value); 1381 &visible_end_token_pos, &var_value);
1155 if (var_name.raw() != Symbols::AsyncOperation().raw()) { 1382 if ((var_name.raw() != Symbols::AsyncOperation().raw()) &&
1383 (var_name.raw() != Symbols::AsyncCompleter().raw()) &&
1384 (var_name.raw() != Symbols::ControllerStream().raw()) &&
1385 (var_name.raw() != Symbols::AwaitJumpVar().raw())) {
1156 JSONObject jsvar(&jsvars); 1386 JSONObject jsvar(&jsvars);
1157 jsvar.AddProperty("type", "BoundVariable"); 1387 jsvar.AddProperty("type", "BoundVariable");
1158 var_name = String::ScrubName(var_name); 1388 var_name = String::ScrubName(var_name);
1159 jsvar.AddProperty("name", var_name.ToCString()); 1389 jsvar.AddProperty("name", var_name.ToCString());
1160 jsvar.AddProperty("value", var_value, !full); 1390 jsvar.AddProperty("value", var_value, !full);
1161 // Where was the variable declared? 1391 // Where was the variable declared?
1162 jsvar.AddProperty("declarationTokenPos", declaration_token_pos); 1392 jsvar.AddProperty("declarationTokenPos", declaration_token_pos);
1163 // When the variable becomes visible to the scope. 1393 // When the variable becomes visible to the scope.
1164 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos); 1394 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos);
1165 // When the variable stops being visible to the scope. 1395 // When the variable stops being visible to the scope.
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 } 1771 }
1542 } 1772 }
1543 } 1773 }
1544 1774
1545 1775
1546 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1776 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1547 uword pc, 1777 uword pc,
1548 StackFrame* frame, 1778 StackFrame* frame,
1549 const Code& code, 1779 const Code& code,
1550 const Array& deopt_frame, 1780 const Array& deopt_frame,
1551 intptr_t deopt_frame_offset) { 1781 intptr_t deopt_frame_offset,
1782 ActivationFrame::Kind kind) {
1552 ASSERT(code.ContainsInstructionAt(pc)); 1783 ASSERT(code.ContainsInstructionAt(pc));
1553 ActivationFrame* activation = new ActivationFrame( 1784 ActivationFrame* activation =
1554 pc, frame->fp(), frame->sp(), code, deopt_frame, deopt_frame_offset); 1785 new ActivationFrame(pc, frame->fp(), frame->sp(), code, deopt_frame,
1786 deopt_frame_offset, kind);
1555 if (FLAG_trace_debugger_stacktrace) { 1787 if (FLAG_trace_debugger_stacktrace) {
1556 const Context& ctx = activation->GetSavedCurrentContext(); 1788 const Context& ctx = activation->GetSavedCurrentContext();
1557 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); 1789 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString());
1558 } 1790 }
1559 if (FLAG_trace_debugger_stacktrace) { 1791 if (FLAG_trace_debugger_stacktrace) {
1560 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); 1792 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
1561 } 1793 }
1562 return activation; 1794 return activation;
1563 } 1795 }
1564 1796
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 } 1953 }
1722 } 1954 }
1723 } 1955 }
1724 // Follow the link. 1956 // Follow the link.
1725 async_stack_trace = async_stack_trace.async_link(); 1957 async_stack_trace = async_stack_trace.async_link();
1726 } 1958 }
1727 1959
1728 return stack_trace; 1960 return stack_trace;
1729 } 1961 }
1730 1962
1963
1964 DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
1965 if (!FLAG_causal_async_stacks) {
1966 return NULL;
1967 }
1968 Thread* thread = Thread::Current();
1969 Zone* zone = thread->zone();
1970 Isolate* isolate = thread->isolate();
1971 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1972
1973 StackFrameIterator iterator(false);
1974
1975 Code& code = Code::Handle(zone);
1976 Function& function = Function::Handle(zone);
1977 Code& inlined_code = Code::Handle(zone);
1978 Closure& async_activation = Closure::Handle(zone);
1979 Array& deopt_frame = Array::Handle(zone);
1980
1981 for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
1982 frame = iterator.NextFrame()) {
1983 ASSERT(frame->IsValid());
1984 if (frame->IsDartFrame()) {
1985 code = frame->LookupDartCode();
1986 function = code.function();
1987 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
1988 ActivationFrame* activation = CollectDartFrame(
1989 isolate, frame->pc(), frame, code, Object::null_array(), 0,
1990 ActivationFrame::kAsyncActivation);
1991 ASSERT(activation != NULL);
1992 stack_trace->AddActivation(activation);
1993 // Grab the awaiter.
1994 async_activation ^= activation->GetAsyncAwaiter();
1995 break;
1996 } else {
1997 AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
1998 &inlined_code, &deopt_frame);
1999 }
2000 }
2001 }
2002
2003 // Return NULL to indicate that there is no useful information in this stack
2004 // trace because we never found an awaiter.
2005 if (async_activation.IsNull()) {
2006 return NULL;
2007 }
2008
2009 // Append the awaiter return call stack.
2010 while (!async_activation.IsNull()) {
2011 ActivationFrame* activation = new ActivationFrame(async_activation);
2012 async_activation ^= activation->GetAsyncAwaiter();
2013 activation->ExtractTokenPositionFromAsyncClosure();
2014 stack_trace->AddActivation(activation);
2015 }
2016
2017 return stack_trace;
2018 }
2019
2020
1731 ActivationFrame* Debugger::TopDartFrame() const { 2021 ActivationFrame* Debugger::TopDartFrame() const {
1732 StackFrameIterator iterator(false); 2022 StackFrameIterator iterator(false);
1733 StackFrame* frame = iterator.NextFrame(); 2023 StackFrame* frame = iterator.NextFrame();
1734 while ((frame != NULL) && !frame->IsDartFrame()) { 2024 while ((frame != NULL) && !frame->IsDartFrame()) {
1735 frame = iterator.NextFrame(); 2025 frame = iterator.NextFrame();
1736 } 2026 }
1737 Code& code = Code::Handle(frame->LookupDartCode()); 2027 Code& code = Code::Handle(frame->LookupDartCode());
1738 ActivationFrame* activation = new ActivationFrame( 2028 ActivationFrame* activation = new ActivationFrame(
1739 frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0); 2029 frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0);
1740 return activation; 2030 return activation;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 (pause_info == kPauseOnAllExceptions)); 2111 (pause_info == kPauseOnAllExceptions));
1822 exc_pause_info_ = pause_info; 2112 exc_pause_info_ = pause_info;
1823 } 2113 }
1824 2114
1825 2115
1826 Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const { 2116 Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const {
1827 return exc_pause_info_; 2117 return exc_pause_info_;
1828 } 2118 }
1829 2119
1830 2120
2121 bool Debugger::ShouldPauseOnAsyncException(DebuggerStackTrace* stack_trace,
2122 const Instance& exc) {
2123 if (exc_pause_info_ == kNoPauseOnExceptions) {
2124 return false;
2125 }
2126 if (exc_pause_info_ == kPauseOnAllExceptions) {
2127 return true;
2128 }
2129 ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions);
2130 for (intptr_t i = 0; i < stack_trace->Length(); i++) {
2131 ActivationFrame* frame = stack_trace->FrameAt(i);
2132 if (frame->HandlesException(exc)) {
2133 OS::PrintErr("%s is caught by frame %s\n", exc.ToCString(),
rmacnak 2017/02/23 17:50:56 if (FLAG_verbose_debug)
Cutch 2017/02/24 20:19:21 Done.
2134 frame->ToCString());
2135 return false;
2136 }
2137 }
2138 return true;
2139 }
2140
2141
1831 bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace, 2142 bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
1832 const Instance& exception) { 2143 const Instance& exception) {
1833 if (exc_pause_info_ == kNoPauseOnExceptions) { 2144 if (exc_pause_info_ == kNoPauseOnExceptions) {
1834 return false; 2145 return false;
1835 } 2146 }
1836 if (exc_pause_info_ == kPauseOnAllExceptions) { 2147 if (exc_pause_info_ == kPauseOnAllExceptions) {
1837 return true; 2148 return true;
1838 } 2149 }
1839 ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions); 2150 ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions);
1840 ActivationFrame* handler_frame = stack_trace->GetHandlerFrame(exception); 2151 ActivationFrame* handler_frame = stack_trace->GetHandlerFrame(exception);
(...skipping 11 matching lines...) Expand all
1852 2163
1853 void Debugger::PauseException(const Instance& exc) { 2164 void Debugger::PauseException(const Instance& exc) {
1854 // We ignore this exception event when the VM is executing code invoked 2165 // We ignore this exception event when the VM is executing code invoked
1855 // by the debugger to evaluate variables values, when we see a nested 2166 // by the debugger to evaluate variables values, when we see a nested
1856 // breakpoint or exception event, or if the debugger is not 2167 // breakpoint or exception event, or if the debugger is not
1857 // interested in exception events. 2168 // interested in exception events.
1858 if (ignore_breakpoints_ || IsPaused() || 2169 if (ignore_breakpoints_ || IsPaused() ||
1859 (exc_pause_info_ == kNoPauseOnExceptions)) { 2170 (exc_pause_info_ == kNoPauseOnExceptions)) {
1860 return; 2171 return;
1861 } 2172 }
2173 DebuggerStackTrace* awaiter_stack_trace = CollectAwaiterReturnStackTrace();
1862 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2174 DebuggerStackTrace* stack_trace = CollectStackTrace();
1863 if (!ShouldPauseOnException(stack_trace, exc)) { 2175 if (awaiter_stack_trace != NULL) {
1864 return; 2176 if (!ShouldPauseOnAsyncException(awaiter_stack_trace, exc)) {
2177 return;
2178 }
2179 } else {
2180 if (!ShouldPauseOnException(stack_trace, exc)) {
2181 return;
2182 }
1865 } 2183 }
1866 ServiceEvent event(isolate_, ServiceEvent::kPauseException); 2184 ServiceEvent event(isolate_, ServiceEvent::kPauseException);
1867 event.set_exception(&exc); 2185 event.set_exception(&exc);
1868 if (stack_trace->Length() > 0) { 2186 if (stack_trace->Length() > 0) {
1869 event.set_top_frame(stack_trace->FrameAt(0)); 2187 event.set_top_frame(stack_trace->FrameAt(0));
1870 } 2188 }
1871 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace()); 2189 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace());
1872 Pause(&event); 2190 Pause(&event);
1873 HandleSteppingRequest(stack_trace_); // we may get a rewind request 2191 HandleSteppingRequest(stack_trace_); // we may get a rewind request
1874 ClearCachedStackTraces(); 2192 ClearCachedStackTraces();
(...skipping 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
3831 4149
3832 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 4150 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3833 ASSERT(bpt->next() == NULL); 4151 ASSERT(bpt->next() == NULL);
3834 bpt->set_next(code_breakpoints_); 4152 bpt->set_next(code_breakpoints_);
3835 code_breakpoints_ = bpt; 4153 code_breakpoints_ = bpt;
3836 } 4154 }
3837 4155
3838 #endif // !PRODUCT 4156 #endif // !PRODUCT
3839 4157
3840 } // namespace dart 4158 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698