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" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 119 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
120 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 120 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 | 124 |
125 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 125 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
126 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 126 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
127 } | 127 } |
128 | 128 |
129 | 129 ActivationFrame::ActivationFrame( |
130 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, const Code& code) | 130 uword pc, |
131 uword fp, | |
132 uword sp, | |
133 const Code& code, | |
134 const Array& deopt_frame, | |
135 intptr_t deopt_frame_offset) | |
131 : pc_(pc), fp_(fp), sp_(sp), | 136 : pc_(pc), fp_(fp), sp_(sp), |
132 ctx_(Context::ZoneHandle()), | 137 ctx_(Context::ZoneHandle()), |
133 code_(Code::ZoneHandle(code.raw())), | 138 code_(Code::ZoneHandle(code.raw())), |
134 function_(Function::ZoneHandle(code.function())), | 139 function_(Function::ZoneHandle(code.function())), |
135 token_pos_(-1), | 140 token_pos_(-1), |
136 pc_desc_index_(-1), | 141 pc_desc_index_(-1), |
137 line_number_(-1), | 142 line_number_(-1), |
138 context_level_(-1), | 143 context_level_(-1), |
139 deopt_frame_(Array::ZoneHandle()), | 144 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), |
140 deopt_frame_offset_(0), | 145 deopt_frame_offset_(deopt_frame_offset), |
141 vars_initialized_(false), | 146 vars_initialized_(false), |
142 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 147 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
143 desc_indices_(8), | 148 desc_indices_(8), |
144 pc_desc_(PcDescriptors::ZoneHandle()) { | 149 pc_desc_(PcDescriptors::ZoneHandle()) { |
145 } | 150 } |
146 | 151 |
147 | 152 |
148 void Debugger::SignalIsolateEvent(EventType type) { | 153 void Debugger::SignalIsolateEvent(EventType type) { |
149 if (event_handler_ != NULL) { | 154 if (event_handler_ != NULL) { |
150 Debugger* debugger = Isolate::Current()->debugger(); | 155 Debugger* debugger = Isolate::Current()->debugger(); |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
573 ASSERT(end_pos != NULL); | 578 ASSERT(end_pos != NULL); |
574 *end_pos = var_info.end_pos; | 579 *end_pos = var_info.end_pos; |
575 ASSERT(value != NULL); | 580 ASSERT(value != NULL); |
576 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 581 if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
577 *value = GetLocalInstanceVar(var_info.index); | 582 *value = GetLocalInstanceVar(var_info.index); |
578 } else { | 583 } else { |
579 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 584 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
580 // The context level at the PC/token index of this activation frame. | 585 // The context level at the PC/token index of this activation frame. |
581 intptr_t frame_ctx_level = ContextLevel(); | 586 intptr_t frame_ctx_level = ContextLevel(); |
582 if (ctx_.IsNull()) { | 587 if (ctx_.IsNull()) { |
588 if (FLAG_use_new_stacktrace) { | |
589 UNREACHABLE(); // ctx_ should never be null. | |
590 } | |
583 *value = Symbols::New("<unknown>"); | 591 *value = Symbols::New("<unknown>"); |
584 return; | 592 return; |
585 } | 593 } |
586 // The context level of the variable. | 594 // The context level of the variable. |
587 intptr_t var_ctx_level = var_info.scope_id; | 595 intptr_t var_ctx_level = var_info.scope_id; |
588 intptr_t level_diff = frame_ctx_level - var_ctx_level; | 596 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
589 intptr_t ctx_slot = var_info.index; | 597 intptr_t ctx_slot = var_info.index; |
590 if (level_diff == 0) { | 598 if (level_diff == 0) { |
591 // TODO(12767) : Need to ensure that we end up with the correct context | 599 // TODO(12767) : Need to ensure that we end up with the correct context |
592 // here so that this check can be an assert. | 600 // here so that this check can be an assert. |
593 if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) { | 601 if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) { |
594 *value = ctx_.At(ctx_slot); | 602 *value = ctx_.At(ctx_slot); |
595 } else { | 603 } else { |
604 if (FLAG_use_new_stacktrace) { | |
605 UNREACHABLE(); // ctx_ should be correct. | |
606 } | |
596 *value = Symbols::New("<unknown>"); | 607 *value = Symbols::New("<unknown>"); |
597 } | 608 } |
598 } else { | 609 } else { |
599 ASSERT(level_diff > 0); | 610 ASSERT(level_diff > 0); |
600 Context& var_ctx = Context::Handle(ctx_.raw()); | 611 Context& var_ctx = Context::Handle(ctx_.raw()); |
601 while (level_diff > 0 && !var_ctx.IsNull()) { | 612 while (level_diff > 0 && !var_ctx.IsNull()) { |
602 level_diff--; | 613 level_diff--; |
603 var_ctx = var_ctx.parent(); | 614 var_ctx = var_ctx.parent(); |
604 } | 615 } |
605 // TODO(12767) : Need to ensure that we end up with the correct context | 616 // TODO(12767) : Need to ensure that we end up with the correct context |
606 // here so that this check can be assert. | 617 // here so that this check can be assert. |
607 if (!var_ctx.IsNull() && | 618 if (!var_ctx.IsNull() && |
608 ((ctx_slot < var_ctx.num_variables()) && (ctx_slot >= 0))) { | 619 ((ctx_slot < var_ctx.num_variables()) && (ctx_slot >= 0))) { |
609 *value = var_ctx.At(ctx_slot); | 620 *value = var_ctx.At(ctx_slot); |
610 } else { | 621 } else { |
622 if (FLAG_use_new_stacktrace) { | |
623 UNREACHABLE(); // var_ctx should be correct. | |
624 } | |
611 *value = Symbols::New("<unknown>"); | 625 *value = Symbols::New("<unknown>"); |
612 } | 626 } |
613 } | 627 } |
614 } | 628 } |
615 } | 629 } |
616 | 630 |
617 | 631 |
618 RawArray* ActivationFrame::GetLocalVariables() { | 632 RawArray* ActivationFrame::GetLocalVariables() { |
619 GetDescIndices(); | 633 GetDescIndices(); |
620 intptr_t num_variables = desc_indices_.length(); | 634 intptr_t num_variables = desc_indices_.length(); |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1016 current.ToFullyQualifiedCString(), | 1030 current.ToFullyQualifiedCString(), |
1017 callee.ToFullyQualifiedCString(), | 1031 callee.ToFullyQualifiedCString(), |
1018 line, col); | 1032 line, col); |
1019 } | 1033 } |
1020 | 1034 |
1021 | 1035 |
1022 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, | 1036 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, |
1023 uword pc, | 1037 uword pc, |
1024 StackFrame* frame, | 1038 StackFrame* frame, |
1025 const Code& code, | 1039 const Code& code, |
1026 bool optimized, | 1040 const Array& deopt_frame, |
1041 intptr_t deopt_frame_offset, | |
1027 ActivationFrame* callee_activation, | 1042 ActivationFrame* callee_activation, |
1028 const Context& entry_ctx) { | 1043 const Context& entry_ctx) { |
1029 // We never provide both a callee activation and an entry context. | 1044 // We provide either a callee activation or an entry context. Not both. |
1030 ASSERT((callee_activation == NULL) || entry_ctx.IsNull()); | 1045 ASSERT((callee_activation == NULL) || entry_ctx.IsNull()); |
1046 ASSERT((callee_activation != NULL) || !entry_ctx.IsNull()); | |
siva
2013/10/15 17:39:12
The two asserts seem hard to read together, I am w
turnidge
2013/10/15 18:07:28
Done.
| |
1031 ActivationFrame* activation = | 1047 ActivationFrame* activation = |
1032 new ActivationFrame(pc, frame->fp(), frame->sp(), code); | 1048 new ActivationFrame(pc, frame->fp(), frame->sp(), code, |
1049 deopt_frame, deopt_frame_offset); | |
1033 | 1050 |
1034 // Recover the context for this frame. | 1051 // Recover the context for this frame. |
1035 if (optimized) { | 1052 if (callee_activation == NULL) { |
1036 // Bail out for optimized frames for now. | |
1037 activation->SetContext(Context::Handle(isolate)); | |
1038 | |
1039 } else if (callee_activation == NULL) { | |
1040 // No callee. Use incoming entry context. Could be from | 1053 // No callee. Use incoming entry context. Could be from |
1041 // isolate's top context or from an entry frame. | 1054 // isolate's top context or from an entry frame. |
1042 activation->SetContext(entry_ctx); | 1055 activation->SetContext(entry_ctx); |
1043 | 1056 |
1044 } else if (callee_activation->function().IsClosureFunction()) { | 1057 } else if (callee_activation->function().IsClosureFunction()) { |
1045 // If the callee is a closure, we should have stored the context | 1058 // If the callee is a closure, we should have stored the context |
1046 // in the current frame before making the call. | 1059 // in the current frame before making the call. |
1047 const Context& closure_call_ctx = | 1060 const Context& closure_call_ctx = |
1048 Context::Handle(isolate, activation->GetSavedCurrentContext()); | 1061 Context::Handle(isolate, activation->GetSavedCurrentContext()); |
1049 activation->SetContext(closure_call_ctx); | 1062 activation->SetContext(closure_call_ctx); |
1050 | 1063 |
1051 // Sometimes there is no saved context. This is a bug. | 1064 // Sometimes there is no saved context. This is a bug. |
1052 // https://code.google.com/p/dart/issues/detail?id=12767 | 1065 // https://code.google.com/p/dart/issues/detail?id=12767 |
1053 if (FLAG_verbose_debug && closure_call_ctx.IsNull()) { | 1066 if ((FLAG_verbose_debug || FLAG_use_new_stacktrace) && |
1067 closure_call_ctx.IsNull()) { | |
1054 PrintStackTraceError( | 1068 PrintStackTraceError( |
1055 "Expected to find saved context for call to closure function", | 1069 "Expected to find saved context for call to closure function", |
1056 activation, callee_activation); | 1070 activation, callee_activation); |
1071 if (FLAG_use_new_stacktrace) { | |
1072 UNREACHABLE(); // This bug should be fixed with new stack collection. | |
1073 } | |
1057 } | 1074 } |
1058 | 1075 |
1059 } else { | 1076 } else { |
1060 // Use the context provided by our callee. This is either the | 1077 // Use the context provided by our callee. This is either the |
1061 // callee's context or a context that was saved in the callee's | 1078 // callee's context or a context that was saved in the callee's |
1062 // frame. | 1079 // frame. |
1063 const Context& callee_ctx = | 1080 const Context& callee_ctx = |
1064 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew()); | 1081 Context::Handle(isolate, callee_activation->GetSavedEntryContextNew()); |
1065 activation->SetContext(callee_ctx); | 1082 activation->SetContext(callee_ctx); |
1066 } | 1083 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 deopt_frame = DeoptimizeToArray(isolate, frame, code); | 1132 deopt_frame = DeoptimizeToArray(isolate, frame, code); |
1116 for (InlinedFunctionsIterator it(code, frame->pc()); | 1133 for (InlinedFunctionsIterator it(code, frame->pc()); |
1117 !it.Done(); | 1134 !it.Done(); |
1118 it.Advance()) { | 1135 it.Advance()) { |
1119 inlined_code = it.code(); | 1136 inlined_code = it.code(); |
1120 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); | 1137 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); |
1121 current_activation = CollectDartFrame(isolate, | 1138 current_activation = CollectDartFrame(isolate, |
1122 it.pc(), | 1139 it.pc(), |
1123 frame, | 1140 frame, |
1124 inlined_code, | 1141 inlined_code, |
1125 true, | 1142 deopt_frame, |
1143 deopt_frame_offset, | |
1126 current_activation, | 1144 current_activation, |
1127 entry_ctx); | 1145 entry_ctx); |
1128 current_activation->SetDeoptFrame(deopt_frame, deopt_frame_offset); | |
1129 stack_trace->AddActivation(current_activation); | 1146 stack_trace->AddActivation(current_activation); |
1130 entry_ctx = Context::null(); // Only use entry context once. | 1147 entry_ctx = Context::null(); // Only use entry context once. |
1131 } | 1148 } |
1132 } else { | 1149 } else { |
1133 current_activation = CollectDartFrame(isolate, | 1150 current_activation = CollectDartFrame(isolate, |
1134 frame->pc(), | 1151 frame->pc(), |
1135 frame, | 1152 frame, |
1136 code, | 1153 code, |
1137 false, | 1154 Object::null_array(), |
1155 0, | |
1138 current_activation, | 1156 current_activation, |
1139 entry_ctx); | 1157 entry_ctx); |
1140 stack_trace->AddActivation(current_activation); | 1158 stack_trace->AddActivation(current_activation); |
1141 entry_ctx = Context::null(); // Only use entry context once. | 1159 entry_ctx = Context::null(); // Only use entry context once. |
1142 } | 1160 } |
1143 } | 1161 } |
1144 } | 1162 } |
1145 return stack_trace; | 1163 return stack_trace; |
1146 } | 1164 } |
1147 | 1165 |
(...skipping 12 matching lines...) Expand all Loading... | |
1160 StackFrameIterator iterator(false); | 1178 StackFrameIterator iterator(false); |
1161 ActivationFrame* callee_activation = NULL; | 1179 ActivationFrame* callee_activation = NULL; |
1162 bool optimized_frame_found = false; | 1180 bool optimized_frame_found = false; |
1163 for (StackFrame* frame = iterator.NextFrame(); | 1181 for (StackFrame* frame = iterator.NextFrame(); |
1164 frame != NULL; | 1182 frame != NULL; |
1165 frame = iterator.NextFrame()) { | 1183 frame = iterator.NextFrame()) { |
1166 ASSERT(frame->IsValid()); | 1184 ASSERT(frame->IsValid()); |
1167 if (frame->IsDartFrame()) { | 1185 if (frame->IsDartFrame()) { |
1168 code = frame->LookupDartCode(); | 1186 code = frame->LookupDartCode(); |
1169 ActivationFrame* activation = | 1187 ActivationFrame* activation = |
1170 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code); | 1188 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
1189 Object::null_array(), 0); | |
1171 // If this activation frame called a closure, the function has | 1190 // If this activation frame called a closure, the function has |
1172 // saved its context before the call. | 1191 // saved its context before the call. |
1173 if ((callee_activation != NULL) && | 1192 if ((callee_activation != NULL) && |
1174 (callee_activation->function().IsClosureFunction())) { | 1193 (callee_activation->function().IsClosureFunction())) { |
1175 ctx = activation->GetSavedCurrentContext(); | 1194 ctx = activation->GetSavedCurrentContext(); |
1176 if (FLAG_verbose_debug && ctx.IsNull()) { | 1195 if (FLAG_verbose_debug && ctx.IsNull()) { |
1177 const Function& caller = activation->function(); | 1196 const Function& caller = activation->function(); |
1178 const Function& callee = callee_activation->function(); | 1197 const Function& callee = callee_activation->function(); |
1179 const Script& script = | 1198 const Script& script = |
1180 Script::Handle(Class::Handle(caller.Owner()).script()); | 1199 Script::Handle(Class::Handle(caller.Owner()).script()); |
(...skipping 29 matching lines...) Expand all Loading... | |
1210 | 1229 |
1211 | 1230 |
1212 ActivationFrame* Debugger::TopDartFrame() const { | 1231 ActivationFrame* Debugger::TopDartFrame() const { |
1213 StackFrameIterator iterator(false); | 1232 StackFrameIterator iterator(false); |
1214 StackFrame* frame = iterator.NextFrame(); | 1233 StackFrame* frame = iterator.NextFrame(); |
1215 while ((frame != NULL) && !frame->IsDartFrame()) { | 1234 while ((frame != NULL) && !frame->IsDartFrame()) { |
1216 frame = iterator.NextFrame(); | 1235 frame = iterator.NextFrame(); |
1217 } | 1236 } |
1218 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); | 1237 Code& code = Code::Handle(isolate_, frame->LookupDartCode()); |
1219 ActivationFrame* activation = | 1238 ActivationFrame* activation = |
1220 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code); | 1239 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
1240 Object::null_array(), 0); | |
1221 return activation; | 1241 return activation; |
1222 } | 1242 } |
1223 | 1243 |
1224 | 1244 |
1225 DebuggerStackTrace* Debugger::StackTrace() { | 1245 DebuggerStackTrace* Debugger::StackTrace() { |
1226 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); | 1246 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); |
1227 } | 1247 } |
1228 | 1248 |
1229 | 1249 |
1230 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) { | 1250 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) { |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2084 } | 2104 } |
2085 | 2105 |
2086 | 2106 |
2087 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2107 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
2088 ASSERT(bpt->next() == NULL); | 2108 ASSERT(bpt->next() == NULL); |
2089 bpt->set_next(code_breakpoints_); | 2109 bpt->set_next(code_breakpoints_); |
2090 code_breakpoints_ = bpt; | 2110 code_breakpoints_ = bpt; |
2091 } | 2111 } |
2092 | 2112 |
2093 } // namespace dart | 2113 } // namespace dart |
OLD | NEW |