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

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

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

Powered by Google App Engine
This is Rietveld 408576698