| 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 "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| 11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/deopt_instructions.h" | 13 #include "vm/deopt_instructions.h" |
| 14 #include "vm/flags.h" | 14 #include "vm/flags.h" |
| 15 #include "vm/globals.h" | 15 #include "vm/globals.h" |
| 16 #include "vm/longjump.h" | 16 #include "vm/longjump.h" |
| 17 #include "vm/object.h" | 17 #include "vm/object.h" |
| 18 #include "vm/object_store.h" | 18 #include "vm/object_store.h" |
| 19 #include "vm/os.h" | 19 #include "vm/os.h" |
| 20 #include "vm/port.h" | 20 #include "vm/port.h" |
| 21 #include "vm/stack_frame.h" | 21 #include "vm/stack_frame.h" |
| 22 #include "vm/stub_code.h" | 22 #include "vm/stub_code.h" |
| 23 #include "vm/symbols.h" | 23 #include "vm/symbols.h" |
| 24 #include "vm/visitor.h" | 24 #include "vm/visitor.h" |
| 25 | 25 |
| 26 | 26 |
| 27 namespace dart { | 27 namespace dart { |
| 28 | 28 |
| 29 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); | 29 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); |
| 30 DEFINE_FLAG(bool, use_new_stacktrace, true, | |
| 31 "Use new stacktrace creation"); | |
| 32 | 30 |
| 33 | 31 |
| 34 Debugger::EventHandler* Debugger::event_handler_ = NULL; | 32 Debugger::EventHandler* Debugger::event_handler_ = NULL; |
| 35 | 33 |
| 36 | 34 |
| 37 class RemoteObjectCache : public ZoneAllocated { | 35 class RemoteObjectCache : public ZoneAllocated { |
| 38 public: | 36 public: |
| 39 explicit RemoteObjectCache(intptr_t initial_size); | 37 explicit RemoteObjectCache(intptr_t initial_size); |
| 40 intptr_t AddObject(const Object& obj); | 38 intptr_t AddObject(const Object& obj); |
| 41 RawObject* GetObj(intptr_t obj_id) const; | 39 RawObject* GetObj(intptr_t obj_id) const; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 context_level_ = var_info.index; | 357 context_level_ = var_info.index; |
| 360 } | 358 } |
| 361 } | 359 } |
| 362 } | 360 } |
| 363 ASSERT(context_level_ >= 0); | 361 ASSERT(context_level_ >= 0); |
| 364 } | 362 } |
| 365 return context_level_; | 363 return context_level_; |
| 366 } | 364 } |
| 367 | 365 |
| 368 | 366 |
| 369 // Get the caller's context, or return ctx if the function does not | 367 RawContext* ActivationFrame::GetSavedEntryContext() { |
| 370 // save the caller's context on entry. | |
| 371 RawContext* ActivationFrame::GetSavedEntryContext(const Context& ctx) { | |
| 372 GetVarDescriptors(); | |
| 373 intptr_t var_desc_len = var_descriptors_.Length(); | |
| 374 for (intptr_t i = 0; i < var_desc_len; i++) { | |
| 375 RawLocalVarDescriptors::VarInfo var_info; | |
| 376 var_descriptors_.GetInfo(i, &var_info); | |
| 377 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { | |
| 378 return GetLocalContextVar(var_info.index); | |
| 379 } | |
| 380 } | |
| 381 return ctx.raw(); | |
| 382 } | |
| 383 | |
| 384 | |
| 385 RawContext* ActivationFrame::GetSavedEntryContextNew() { | |
| 386 if (ctx_.IsNull()) { | 368 if (ctx_.IsNull()) { |
| 387 // We have bailed on providing a context for this frame. Bail for | 369 // We have bailed on providing a context for this frame. Bail for |
| 388 // the caller as well. | 370 // the caller as well. |
| 389 return Context::null(); | 371 return Context::null(); |
| 390 } | 372 } |
| 391 | 373 |
| 392 // Attempt to find a saved context. | 374 // Attempt to find a saved context. |
| 393 GetVarDescriptors(); | 375 GetVarDescriptors(); |
| 394 intptr_t var_desc_len = var_descriptors_.Length(); | 376 intptr_t var_desc_len = var_descriptors_.Length(); |
| 395 for (intptr_t i = 0; i < var_desc_len; i++) { | 377 for (intptr_t i = 0; i < var_desc_len; i++) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 return NULL; | 441 return NULL; |
| 460 } | 442 } |
| 461 | 443 |
| 462 | 444 |
| 463 void ActivationFrame::GetDescIndices() { | 445 void ActivationFrame::GetDescIndices() { |
| 464 if (vars_initialized_) { | 446 if (vars_initialized_) { |
| 465 return; | 447 return; |
| 466 } | 448 } |
| 467 GetVarDescriptors(); | 449 GetVarDescriptors(); |
| 468 | 450 |
| 469 // We don't trust variable descriptors in optimized code. | |
| 470 // Rather than potentially displaying incorrect values, we | |
| 471 // pretend that there are no variables in the frame. | |
| 472 // We should be more clever about this in the future. | |
| 473 if (!FLAG_use_new_stacktrace && code().is_optimized()) { | |
| 474 vars_initialized_ = true; | |
| 475 return; | |
| 476 } | |
| 477 | |
| 478 intptr_t activation_token_pos = TokenPos(); | 451 intptr_t activation_token_pos = TokenPos(); |
| 479 if (activation_token_pos < 0) { | 452 if (activation_token_pos < 0) { |
| 480 // We don't have a token position for this frame, so can't determine | 453 // We don't have a token position for this frame, so can't determine |
| 481 // which variables are visible. | 454 // which variables are visible. |
| 482 vars_initialized_ = true; | 455 vars_initialized_ = true; |
| 483 return; | 456 return; |
| 484 } | 457 } |
| 485 | 458 |
| 486 GrowableArray<String*> var_names(8); | 459 GrowableArray<String*> var_names(8); |
| 487 intptr_t var_desc_len = var_descriptors_.Length(); | 460 intptr_t var_desc_len = var_descriptors_.Length(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 *token_pos = var_info.begin_pos; | 564 *token_pos = var_info.begin_pos; |
| 592 ASSERT(end_pos != NULL); | 565 ASSERT(end_pos != NULL); |
| 593 *end_pos = var_info.end_pos; | 566 *end_pos = var_info.end_pos; |
| 594 ASSERT(value != NULL); | 567 ASSERT(value != NULL); |
| 595 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 568 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
| 596 *value = GetLocalInstanceVar(var_info.index); | 569 *value = GetLocalInstanceVar(var_info.index); |
| 597 } else { | 570 } else { |
| 598 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 571 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
| 599 // The context level at the PC/token index of this activation frame. | 572 // The context level at the PC/token index of this activation frame. |
| 600 intptr_t frame_ctx_level = ContextLevel(); | 573 intptr_t frame_ctx_level = ContextLevel(); |
| 601 if (ctx_.IsNull()) { | 574 ASSERT(!ctx_.IsNull()); |
| 602 if (FLAG_use_new_stacktrace) { | 575 |
| 603 UNREACHABLE(); // ctx_ should never be null. | |
| 604 } | |
| 605 *value = Symbols::New("<unknown>"); | |
| 606 return; | |
| 607 } | |
| 608 // The context level of the variable. | 576 // The context level of the variable. |
| 609 intptr_t var_ctx_level = var_info.scope_id; | 577 intptr_t var_ctx_level = var_info.scope_id; |
| 610 intptr_t level_diff = frame_ctx_level - var_ctx_level; | 578 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
| 611 intptr_t ctx_slot = var_info.index; | 579 intptr_t ctx_slot = var_info.index; |
| 612 if (level_diff == 0) { | 580 if (level_diff == 0) { |
| 613 // TODO(12767) : Need to ensure that we end up with the correct context | 581 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx_.num_variables())); |
| 614 // here so that this check can be an assert. | 582 *value = ctx_.At(ctx_slot); |
| 615 if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) { | |
| 616 *value = ctx_.At(ctx_slot); | |
| 617 } else { | |
| 618 if (FLAG_use_new_stacktrace) { | |
| 619 UNREACHABLE(); // ctx_ should be correct. | |
| 620 } | |
| 621 *value = Symbols::New("<unknown>"); | |
| 622 } | |
| 623 } else { | 583 } else { |
| 624 ASSERT(level_diff > 0); | 584 ASSERT(level_diff > 0); |
| 625 Context& var_ctx = Context::Handle(ctx_.raw()); | 585 Context& var_ctx = Context::Handle(ctx_.raw()); |
| 626 while (level_diff > 0 && !var_ctx.IsNull()) { | 586 while (level_diff > 0 && !var_ctx.IsNull()) { |
| 627 level_diff--; | 587 level_diff--; |
| 628 var_ctx = var_ctx.parent(); | 588 var_ctx = var_ctx.parent(); |
| 629 } | 589 } |
| 630 // TODO(12767) : Need to ensure that we end up with the correct context | 590 ASSERT(!var_ctx.IsNull()); |
| 631 // here so that this check can be assert. | 591 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); |
| 632 if (!var_ctx.IsNull() && | 592 *value = var_ctx.At(ctx_slot); |
| 633 ((ctx_slot < var_ctx.num_variables()) && (ctx_slot >= 0))) { | |
| 634 *value = var_ctx.At(ctx_slot); | |
| 635 } else { | |
| 636 if (FLAG_use_new_stacktrace) { | |
| 637 UNREACHABLE(); // var_ctx should be correct. | |
| 638 } | |
| 639 *value = Symbols::New("<unknown>"); | |
| 640 } | |
| 641 } | 593 } |
| 642 } | 594 } |
| 643 } | 595 } |
| 644 | 596 |
| 645 | 597 |
| 646 RawArray* ActivationFrame::GetLocalVariables() { | 598 RawArray* ActivationFrame::GetLocalVariables() { |
| 647 GetDescIndices(); | 599 GetDescIndices(); |
| 648 intptr_t num_variables = desc_indices_.length(); | 600 intptr_t num_variables = desc_indices_.length(); |
| 649 String& var_name = String::Handle(); | 601 String& var_name = String::Handle(); |
| 650 Instance& value = Instance::Handle(); | 602 Instance& value = Instance::Handle(); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 | 995 |
| 1044 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 996 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |
| 1045 if (event_handler_ != NULL) { | 997 if (event_handler_ != NULL) { |
| 1046 DebuggerEvent event(kBreakpointResolved); | 998 DebuggerEvent event(kBreakpointResolved); |
| 1047 event.breakpoint = bpt; | 999 event.breakpoint = bpt; |
| 1048 (*event_handler_)(&event); | 1000 (*event_handler_)(&event); |
| 1049 } | 1001 } |
| 1050 } | 1002 } |
| 1051 | 1003 |
| 1052 | 1004 |
| 1053 static void PrintStackTraceError(const char* message, | |
| 1054 ActivationFrame* current_activation, | |
| 1055 ActivationFrame* callee_activation) { | |
| 1056 const Function& current = current_activation->function(); | |
| 1057 const Function& callee = callee_activation->function(); | |
| 1058 const Script& script = | |
| 1059 Script::Handle(Class::Handle(current.Owner()).script()); | |
| 1060 intptr_t line, col; | |
| 1061 script.GetTokenLocation(current_activation->TokenPos(), &line, &col); | |
| 1062 OS::PrintErr("Error building stack trace: %s:" | |
| 1063 "current function '%s' callee_function '%s' " | |
| 1064 " line %" Pd " column %" Pd "\n", | |
| 1065 message, | |
| 1066 current.ToFullyQualifiedCString(), | |
| 1067 callee.ToFullyQualifiedCString(), | |
| 1068 line, col); | |
| 1069 } | |
| 1070 | |
| 1071 | |
| 1072 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, | 1005 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, |
| 1073 uword pc, | 1006 uword pc, |
| 1074 StackFrame* frame, | 1007 StackFrame* frame, |
| 1075 const Code& code, | 1008 const Code& code, |
| 1076 const Array& deopt_frame, | 1009 const Array& deopt_frame, |
| 1077 intptr_t deopt_frame_offset, | 1010 intptr_t deopt_frame_offset, |
| 1078 ActivationFrame* callee_activation, | 1011 ActivationFrame* callee_activation, |
| 1079 const Context& entry_ctx) { | 1012 const Context& entry_ctx) { |
| 1080 // We provide either a callee activation or an entry context. Not both. | 1013 // We provide either a callee activation or an entry context. Not both. |
| 1081 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || | 1014 ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) || |
| 1082 ((callee_activation == NULL) && !entry_ctx.IsNull())); | 1015 ((callee_activation == NULL) && !entry_ctx.IsNull())); |
| 1083 ActivationFrame* activation = | 1016 ActivationFrame* activation = |
| 1084 new ActivationFrame(pc, frame->fp(), frame->sp(), code, | 1017 new ActivationFrame(pc, frame->fp(), frame->sp(), code, |
| 1085 deopt_frame, deopt_frame_offset); | 1018 deopt_frame, deopt_frame_offset); |
| 1086 | 1019 |
| 1087 // Recover the context for this frame. | 1020 // Recover the context for this frame. |
| 1088 if (callee_activation == NULL) { | 1021 if (callee_activation == NULL) { |
| 1089 // No callee. Use incoming entry context. Could be from | 1022 // No callee. Use incoming entry context. Could be from |
| 1090 // isolate's top context or from an entry frame. | 1023 // isolate's top context or from an entry frame. |
| 1091 activation->SetContext(entry_ctx); | 1024 activation->SetContext(entry_ctx); |
| 1092 | 1025 |
| 1093 } else if (callee_activation->function().IsClosureFunction()) { | 1026 } else if (callee_activation->function().IsClosureFunction()) { |
| 1094 // If the callee is a closure, we should have stored the context | 1027 // If the callee is a closure, we should have stored the context |
| 1095 // in the current frame before making the call. | 1028 // in the current frame before making the call. |
| 1096 const Context& closure_call_ctx = | 1029 const Context& closure_call_ctx = |
| 1097 Context::Handle(isolate, activation->GetSavedCurrentContext()); | 1030 Context::Handle(isolate, activation->GetSavedCurrentContext()); |
| 1031 ASSERT(!closure_call_ctx.IsNull()); |
| 1098 activation->SetContext(closure_call_ctx); | 1032 activation->SetContext(closure_call_ctx); |
| 1099 | 1033 |
| 1100 // Sometimes there is no saved context. This is a bug. | |
| 1101 // https://code.google.com/p/dart/issues/detail?id=12767 | |
| 1102 if ((FLAG_verbose_debug || FLAG_use_new_stacktrace) && | |
| 1103 closure_call_ctx.IsNull()) { | |
| 1104 PrintStackTraceError( | |
| 1105 "Expected to find saved context for call to closure function", | |
| 1106 activation, callee_activation); | |
| 1107 if (FLAG_use_new_stacktrace) { | |
| 1108 UNREACHABLE(); // This bug should be fixed with new stack collection. | |
| 1109 } | |
| 1110 } | |
| 1111 | |
| 1112 } else { | 1034 } else { |
| 1113 // Use the context provided by our callee. This is either the | 1035 // Use the context provided by our callee. This is either the |
| 1114 // callee's context or a context that was saved in the callee's | 1036 // callee's context or a context that was saved in the callee's |
| 1115 // frame. | 1037 // frame. |
| 1116 const Context& callee_ctx = | 1038 const Context& callee_ctx = |
| 1117 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew()); | 1039 Context::Handle(isolate, callee_activation->GetSavedEntryContext()); |
| 1118 activation->SetContext(callee_ctx); | 1040 activation->SetContext(callee_ctx); |
| 1119 } | 1041 } |
| 1120 return activation; | 1042 return activation; |
| 1121 } | 1043 } |
| 1122 | 1044 |
| 1123 | 1045 |
| 1124 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, | 1046 RawArray* Debugger::DeoptimizeToArray(Isolate* isolate, |
| 1125 StackFrame* frame, | 1047 StackFrame* frame, |
| 1126 const Code& code) { | 1048 const Code& code) { |
| 1127 ASSERT(code.is_optimized()); | 1049 ASSERT(code.is_optimized()); |
| 1128 | 1050 |
| 1129 // Create the DeoptContext for this deoptimization. | 1051 // Create the DeoptContext for this deoptimization. |
| 1130 DeoptContext* deopt_context = | 1052 DeoptContext* deopt_context = |
| 1131 new DeoptContext(frame, code, | 1053 new DeoptContext(frame, code, |
| 1132 DeoptContext::kDestIsAllocated, | 1054 DeoptContext::kDestIsAllocated, |
| 1133 NULL, NULL); | 1055 NULL, NULL); |
| 1134 isolate->set_deopt_context(deopt_context); | 1056 isolate->set_deopt_context(deopt_context); |
| 1135 | 1057 |
| 1136 deopt_context->FillDestFrame(); | 1058 deopt_context->FillDestFrame(); |
| 1137 deopt_context->MaterializeDeferredObjects(); | 1059 deopt_context->MaterializeDeferredObjects(); |
| 1138 const Array& dest_frame = Array::Handle(deopt_context->DestFrameAsArray()); | 1060 const Array& dest_frame = Array::Handle(deopt_context->DestFrameAsArray()); |
| 1139 | 1061 |
| 1140 isolate->set_deopt_context(NULL); | 1062 isolate->set_deopt_context(NULL); |
| 1141 delete deopt_context; | 1063 delete deopt_context; |
| 1142 | 1064 |
| 1143 return dest_frame.raw(); | 1065 return dest_frame.raw(); |
| 1144 } | 1066 } |
| 1145 | 1067 |
| 1146 | 1068 |
| 1147 DebuggerStackTrace* Debugger::CollectStackTraceNew() { | 1069 DebuggerStackTrace* Debugger::CollectStackTrace() { |
| 1148 Isolate* isolate = Isolate::Current(); | 1070 Isolate* isolate = Isolate::Current(); |
| 1149 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 1071 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 1150 StackFrameIterator iterator(false); | 1072 StackFrameIterator iterator(false); |
| 1151 ActivationFrame* current_activation = NULL; | 1073 ActivationFrame* current_activation = NULL; |
| 1152 Context& entry_ctx = Context::Handle(isolate->top_context()); | 1074 Context& entry_ctx = Context::Handle(isolate->top_context()); |
| 1153 Code& code = Code::Handle(isolate); | 1075 Code& code = Code::Handle(isolate); |
| 1154 Code& inlined_code = Code::Handle(isolate); | 1076 Code& inlined_code = Code::Handle(isolate); |
| 1155 Array& deopt_frame = Array::Handle(isolate); | 1077 Array& deopt_frame = Array::Handle(isolate); |
| 1156 | 1078 |
| 1157 for (StackFrame* frame = iterator.NextFrame(); | 1079 for (StackFrame* frame = iterator.NextFrame(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 entry_ctx); | 1115 entry_ctx); |
| 1194 stack_trace->AddActivation(current_activation); | 1116 stack_trace->AddActivation(current_activation); |
| 1195 entry_ctx = Context::null(); // Only use entry context once. | 1117 entry_ctx = Context::null(); // Only use entry context once. |
| 1196 } | 1118 } |
| 1197 } | 1119 } |
| 1198 } | 1120 } |
| 1199 return stack_trace; | 1121 return stack_trace; |
| 1200 } | 1122 } |
| 1201 | 1123 |
| 1202 | 1124 |
| 1203 | |
| 1204 DebuggerStackTrace* Debugger::CollectStackTrace() { | |
| 1205 if (FLAG_use_new_stacktrace) { | |
| 1206 // Guard new stack trace generation under a flag in case there are | |
| 1207 // problems rolling it out. | |
| 1208 return CollectStackTraceNew(); | |
| 1209 } | |
| 1210 Isolate* isolate = Isolate::Current(); | |
| 1211 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | |
| 1212 Context& ctx = Context::Handle(isolate->top_context()); | |
| 1213 Code& code = Code::Handle(isolate); | |
| 1214 StackFrameIterator iterator(false); | |
| 1215 ActivationFrame* callee_activation = NULL; | |
| 1216 bool optimized_frame_found = false; | |
| 1217 for (StackFrame* frame = iterator.NextFrame(); | |
| 1218 frame != NULL; | |
| 1219 frame = iterator.NextFrame()) { | |
| 1220 ASSERT(frame->IsValid()); | |
| 1221 if (frame->IsDartFrame()) { | |
| 1222 code = frame->LookupDartCode(); | |
| 1223 ActivationFrame* activation = | |
| 1224 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, | |
| 1225 Object::null_array(), 0); | |
| 1226 // If this activation frame called a closure, the function has | |
| 1227 // saved its context before the call. | |
| 1228 if ((callee_activation != NULL) && | |
| 1229 (callee_activation->function().IsClosureFunction())) { | |
| 1230 ctx = activation->GetSavedCurrentContext(); | |
| 1231 if (FLAG_verbose_debug && ctx.IsNull()) { | |
| 1232 const Function& caller = activation->function(); | |
| 1233 const Function& callee = callee_activation->function(); | |
| 1234 const Script& script = | |
| 1235 Script::Handle(Class::Handle(caller.Owner()).script()); | |
| 1236 intptr_t line, col; | |
| 1237 script.GetTokenLocation(activation->TokenPos(), &line, &col); | |
| 1238 OS::Print("CollectStackTrace error: no saved context in function " | |
| 1239 "'%s' which calls closure '%s' " | |
| 1240 " in line %" Pd " column %" Pd "\n", | |
| 1241 caller.ToFullyQualifiedCString(), | |
| 1242 callee.ToFullyQualifiedCString(), | |
| 1243 line, col); | |
| 1244 } | |
| 1245 } | |
| 1246 if (optimized_frame_found || code.is_optimized()) { | |
| 1247 // Set context to null, to avoid returning bad context variable values. | |
| 1248 activation->SetContext(Context::Handle()); | |
| 1249 optimized_frame_found = true; | |
| 1250 } else { | |
| 1251 ASSERT(!ctx.IsNull()); | |
| 1252 activation->SetContext(ctx); | |
| 1253 } | |
| 1254 stack_trace->AddActivation(activation); | |
| 1255 callee_activation = activation; | |
| 1256 // Get caller's context if this function saved it on entry. | |
| 1257 ctx = activation->GetSavedEntryContext(ctx); | |
| 1258 } else if (frame->IsEntryFrame()) { | |
| 1259 ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext(); | |
| 1260 callee_activation = NULL; | |
| 1261 } | |
| 1262 } | |
| 1263 return stack_trace; | |
| 1264 } | |
| 1265 | |
| 1266 | |
| 1267 ActivationFrame* Debugger::TopDartFrame() const { | 1125 ActivationFrame* Debugger::TopDartFrame() const { |
| 1268 StackFrameIterator iterator(false); | 1126 StackFrameIterator iterator(false); |
| 1269 StackFrame* frame = iterator.NextFrame(); | 1127 StackFrame* frame = iterator.NextFrame(); |
| 1270 while ((frame != NULL) && !frame->IsDartFrame()) { | 1128 while ((frame != NULL) && !frame->IsDartFrame()) { |
| 1271 frame = iterator.NextFrame(); | 1129 frame = iterator.NextFrame(); |
| 1272 } | 1130 } |
| 1273 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); | 1131 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); |
| 1274 ActivationFrame* activation = | 1132 ActivationFrame* activation = |
| 1275 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, | 1133 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
| 1276 Object::null_array(), 0); | 1134 Object::null_array(), 0); |
| 1277 return activation; | 1135 return activation; |
| 1278 } | 1136 } |
| 1279 | 1137 |
| 1280 | 1138 |
| 1281 DebuggerStackTrace* Debugger::StackTrace() { | 1139 DebuggerStackTrace* Debugger::StackTrace() { |
| 1282 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); | 1140 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); |
| 1283 } | 1141 } |
| 1284 | 1142 |
| 1285 DebuggerStackTrace* Debugger::CurrentStackTrace() { | 1143 DebuggerStackTrace* Debugger::CurrentStackTrace() { |
| 1286 return CollectStackTraceNew(); | 1144 return CollectStackTrace(); |
| 1287 } | 1145 } |
| 1288 | 1146 |
| 1289 DebuggerStackTrace* Debugger::StackTraceFrom(const Stacktrace& ex_trace) { | 1147 DebuggerStackTrace* Debugger::StackTraceFrom(const Stacktrace& ex_trace) { |
| 1290 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | 1148 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 1291 Function& function = Function::Handle(); | 1149 Function& function = Function::Handle(); |
| 1292 Code& code = Code::Handle(); | 1150 Code& code = Code::Handle(); |
| 1293 | 1151 |
| 1294 const uword fp = 0; | 1152 const uword fp = 0; |
| 1295 const uword sp = 0; | 1153 const uword sp = 0; |
| 1296 const Array& deopt_frame = Array::Handle(); | 1154 const Array& deopt_frame = Array::Handle(); |
| (...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2238 } | 2096 } |
| 2239 | 2097 |
| 2240 | 2098 |
| 2241 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2099 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2242 ASSERT(bpt->next() == NULL); | 2100 ASSERT(bpt->next() == NULL); |
| 2243 bpt->set_next(code_breakpoints_); | 2101 bpt->set_next(code_breakpoints_); |
| 2244 code_breakpoints_ = bpt; | 2102 code_breakpoints_ = bpt; |
| 2245 } | 2103 } |
| 2246 | 2104 |
| 2247 } // namespace dart | 2105 } // namespace dart |
| OLD | NEW |