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

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

Issue 271153002: Add pause/resume for isolates in vmservice/observatory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
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 "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 token_pos_ = token_pos; 92 token_pos_ = token_pos;
93 end_token_pos_ = token_pos; 93 end_token_pos_ = token_pos;
94 line_number_ = -1; // Recalcualte lazily. 94 line_number_ = -1; // Recalcualte lazily.
95 is_resolved_ = true; 95 is_resolved_ = true;
96 } 96 }
97 97
98 98
99 // TODO(hausner): Get rid of library parameter. A source breakpoint location 99 // TODO(hausner): Get rid of library parameter. A source breakpoint location
100 // does not imply a library, since the same source code can be included 100 // does not imply a library, since the same source code can be included
101 // in more than one library, e.g. the text location of mixin functions. 101 // in more than one library, e.g. the text location of mixin functions.
102 void SourceBreakpoint::GetCodeLocation( 102 void SourceBreakpoint::GetCodeLocation(Library* lib,
103 Library* lib, 103 Script* script,
104 Script* script, 104 intptr_t* pos) {
105 intptr_t* pos) {
106 *script = this->script(); 105 *script = this->script();
107 *pos = token_pos_; 106 *pos = token_pos_;
108 if (IsResolved()) { 107 if (IsResolved()) {
109 const Function& func = Function::Handle(function_); 108 const Function& func = Function::Handle(function_);
110 ASSERT(!func.IsNull()); 109 ASSERT(!func.IsNull());
111 const Class& cls = Class::Handle(func.origin()); 110 const Class& cls = Class::Handle(func.origin());
112 *lib = cls.library(); 111 *lib = cls.library();
113 } else { 112 } else {
114 *lib = Library::null(); 113 *lib = Library::null();
115 } 114 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 context_level_(-1), 184 context_level_(-1),
186 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 185 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
187 deopt_frame_offset_(deopt_frame_offset), 186 deopt_frame_offset_(deopt_frame_offset),
188 vars_initialized_(false), 187 vars_initialized_(false),
189 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 188 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
190 desc_indices_(8), 189 desc_indices_(8),
191 pc_desc_(PcDescriptors::ZoneHandle()) { 190 pc_desc_(PcDescriptors::ZoneHandle()) {
192 } 191 }
193 192
194 193
195 void Debugger::SignalIsolateEvent(EventType type) { 194 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
196 if (event_handler_ != NULL) { 195 if (event_handler_ != NULL) {
197 DebuggerEvent event(type); 196 DebuggerEvent event(type);
198 event.isolate_id = isolate_id_; 197 event.set_isolate_id(isolate_id_);
199 ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID); 198 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
200 if (type == kIsolateInterrupted) { 199 if (type == DebuggerEvent::kIsolateInterrupted) {
201 DebuggerStackTrace* trace = CollectStackTrace(); 200 DebuggerStackTrace* trace = CollectStackTrace();
202 ASSERT(trace->Length() > 0); 201 ASSERT(trace->Length() > 0);
203 ASSERT(stack_trace_ == NULL); 202 ASSERT(stack_trace_ == NULL);
204 stack_trace_ = trace; 203 stack_trace_ = trace;
205 resume_action_ = kContinue; 204 resume_action_ = kContinue;
206 Pause(&event); 205 Pause(&event);
207 HandleSteppingRequest(trace); 206 HandleSteppingRequest(trace);
208 stack_trace_ = NULL; 207 stack_trace_ = NULL;
209 } else { 208 } else {
210 (*event_handler_)(&event); 209 (*event_handler_)(&event);
211 } 210 }
212 } 211 }
213 } 212 }
214 213
215 214
216 void Debugger::SignalIsolateInterrupted() { 215 void Debugger::SignalIsolateInterrupted() {
217 if (event_handler_ != NULL) { 216 if (event_handler_ != NULL) {
218 Debugger* debugger = Isolate::Current()->debugger(); 217 Debugger* debugger = Isolate::Current()->debugger();
219 ASSERT(debugger != NULL); 218 ASSERT(debugger != NULL);
220 debugger->SignalIsolateEvent(kIsolateInterrupted); 219 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
221 } 220 }
222 } 221 }
223 222
224 223
225 const char* Debugger::QualifiedFunctionName(const Function& func) { 224 const char* Debugger::QualifiedFunctionName(const Function& func) {
226 const String& func_name = String::Handle(func.name()); 225 const String& func_name = String::Handle(func.name());
227 Class& func_class = Class::Handle(func.Owner()); 226 Class& func_class = Class::Handle(func.Owner());
228 String& class_name = String::Handle(func_class.Name()); 227 String& class_name = String::Handle(func_class.Name());
229 228
230 const char* kFormat = "%s%s%s"; 229 const char* kFormat = "%s%s%s";
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 var_info.index); 479 var_info.index);
481 } 480 }
482 return GetLocalContextVar(var_info.index); 481 return GetLocalContextVar(var_info.index);
483 } 482 }
484 } 483 }
485 UNREACHABLE(); 484 UNREACHABLE();
486 return Context::null(); 485 return Context::null();
487 } 486 }
488 487
489 488
489 const char* DebuggerEvent::EventTypeToCString(EventType type) {
490 switch (type) {
491 case kBreakpointReached:
492 return "BreakpointReached";
493 case kBreakpointResolved:
494 return "BreakpointResolved";
495 case kExceptionThrown:
496 return "ExceptionThrown";
497 case kIsolateCreated:
498 return "IsolateCreated";
499 case kIsolateShutdown:
500 return "IsolateShutdown";
501 case kIsolateInterrupted:
502 return "IsolateInterrupted";
503 default:
504 UNREACHABLE();
505 return "Unknown";
506 }
507 }
508
509
510 void DebuggerEvent::PrintJSON(JSONStream* js) const {
511 JSONObject jsobj(js);
512 jsobj.AddProperty("type", "DebuggerEvent");
513 // TODO(turnidge): Drop the 'id' for things like DebuggerEvent.
514 jsobj.AddProperty("id", "");
515 // TODO(turnidge): Add 'isolate'.
516 jsobj.AddProperty("eventType", EventTypeToCString(type()));
517 if (type() == kBreakpointResolved || type() == kBreakpointReached) {
518 jsobj.AddProperty("breakpoint", breakpoint());
519 }
520 if (type() == kExceptionThrown) {
521 jsobj.AddProperty("exception", *(exception()));
522 }
523 }
524
525
490 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 526 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
491 const Instance& exc_obj) const { 527 const Instance& exc_obj) const {
492 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); 528 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
493 Array& handled_types = Array::Handle(); 529 Array& handled_types = Array::Handle();
494 AbstractType& type = Type::Handle(); 530 AbstractType& type = Type::Handle();
495 const TypeArguments& no_instantiator = TypeArguments::Handle(); 531 const TypeArguments& no_instantiator = TypeArguments::Handle();
496 for (intptr_t frame_index = 0; 532 for (intptr_t frame_index = 0;
497 frame_index < Length(); 533 frame_index < Length();
498 frame_index++) { 534 frame_index++) {
499 ActivationFrame* frame = FrameAt(frame_index); 535 ActivationFrame* frame = FrameAt(frame_index);
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 src_breakpoints_ = src_breakpoints_->next(); 1059 src_breakpoints_ = src_breakpoints_->next();
1024 delete bpt; 1060 delete bpt;
1025 } 1061 }
1026 while (code_breakpoints_ != NULL) { 1062 while (code_breakpoints_ != NULL) {
1027 CodeBreakpoint* bpt = code_breakpoints_; 1063 CodeBreakpoint* bpt = code_breakpoints_;
1028 code_breakpoints_ = code_breakpoints_->next(); 1064 code_breakpoints_ = code_breakpoints_->next();
1029 bpt->Disable(); 1065 bpt->Disable();
1030 delete bpt; 1066 delete bpt;
1031 } 1067 }
1032 // Signal isolate shutdown event. 1068 // Signal isolate shutdown event.
1033 SignalIsolateEvent(Debugger::kIsolateShutdown); 1069 SignalIsolateEvent(DebuggerEvent::kIsolateShutdown);
1034 } 1070 }
1035 1071
1036 1072
1037 static RawFunction* ResolveLibraryFunction( 1073 static RawFunction* ResolveLibraryFunction(
1038 const Library& library, 1074 const Library& library,
1039 const String& fname) { 1075 const String& fname) {
1040 ASSERT(!library.IsNull()); 1076 ASSERT(!library.IsNull());
1041 const Object& object = Object::Handle(library.ResolveName(fname)); 1077 const Object& object = Object::Handle(library.ResolveName(fname));
1042 if (!object.IsNull() && object.IsFunction()) { 1078 if (!object.IsNull() && object.IsFunction()) {
1043 return Function::Cast(object).raw(); 1079 return Function::Cast(object).raw();
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 bpt = new CodeBreakpoint(code, i); 1205 bpt = new CodeBreakpoint(code, i);
1170 RegisterCodeBreakpoint(bpt); 1206 RegisterCodeBreakpoint(bpt);
1171 bpt->Enable(); 1207 bpt->Enable();
1172 } 1208 }
1173 } 1209 }
1174 } 1210 }
1175 1211
1176 1212
1177 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { 1213 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
1178 if (event_handler_ != NULL) { 1214 if (event_handler_ != NULL) {
1179 DebuggerEvent event(kBreakpointResolved); 1215 DebuggerEvent event(DebuggerEvent::kBreakpointResolved);
1180 event.breakpoint = bpt; 1216 event.set_breakpoint(bpt);
1181 (*event_handler_)(&event); 1217 (*event_handler_)(&event);
1182 } 1218 }
1183 } 1219 }
1184 1220
1185 1221
1186 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1222 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1187 uword pc, 1223 uword pc,
1188 StackFrame* frame, 1224 StackFrame* frame,
1189 const Code& code_param, 1225 const Code& code_param,
1190 const Array& deopt_frame, 1226 const Array& deopt_frame,
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 if (ignore_breakpoints_ || 1509 if (ignore_breakpoints_ ||
1474 IsPaused() || 1510 IsPaused() ||
1475 (event_handler_ == NULL) || 1511 (event_handler_ == NULL) ||
1476 (exc_pause_info_ == kNoPauseOnExceptions)) { 1512 (exc_pause_info_ == kNoPauseOnExceptions)) {
1477 return; 1513 return;
1478 } 1514 }
1479 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1515 DebuggerStackTrace* stack_trace = CollectStackTrace();
1480 if (!ShouldPauseOnException(stack_trace, exc)) { 1516 if (!ShouldPauseOnException(stack_trace, exc)) {
1481 return; 1517 return;
1482 } 1518 }
1483 DebuggerEvent event(kExceptionThrown); 1519 DebuggerEvent event(DebuggerEvent::kExceptionThrown);
1484 event.exception = &exc; 1520 event.set_exception(&exc);
1485 ASSERT(stack_trace_ == NULL); 1521 ASSERT(stack_trace_ == NULL);
1486 stack_trace_ = stack_trace; 1522 stack_trace_ = stack_trace;
1487 Pause(&event); 1523 Pause(&event);
1488 stack_trace_ = NULL; 1524 stack_trace_ = NULL;
1489 } 1525 }
1490 1526
1491 1527
1492 // Given a function and a token range, return the best fit 1528 // Given a function and a token range, return the best fit
1493 // token position to set a breakpoint. The best fit is the safe point 1529 // token position to set a breakpoint. The best fit is the safe point
1494 // with the lowest compiled code address within the token range. 1530 // with the lowest compiled code address within the token range.
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 ActivationFrame* frame = stack_trace->FrameAt(i); 2195 ActivationFrame* frame = stack_trace->FrameAt(i);
2160 if (frame->IsDebuggable()) { 2196 if (frame->IsDebuggable()) {
2161 stepping_fp_ = frame->fp(); 2197 stepping_fp_ = frame->fp();
2162 break; 2198 break;
2163 } 2199 }
2164 } 2200 }
2165 } 2201 }
2166 } 2202 }
2167 2203
2168 2204
2205 // static
2169 bool Debugger::IsDebuggable(const Function& func) { 2206 bool Debugger::IsDebuggable(const Function& func) {
2170 if (!IsDebuggableFunctionKind(func)) { 2207 if (!IsDebuggableFunctionKind(func)) {
2171 return false; 2208 return false;
2172 } 2209 }
2173 const Class& cls = Class::Handle(func.Owner()); 2210 const Class& cls = Class::Handle(func.Owner());
2174 const Library& lib = Library::Handle(cls.library()); 2211 const Library& lib = Library::Handle(cls.library());
2175 return lib.IsDebuggable(); 2212 return lib.IsDebuggable();
2176 } 2213 }
2177 2214
2178 2215
2179 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, 2216 void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
2180 SourceBreakpoint* bpt) { 2217 SourceBreakpoint* bpt) {
2181 resume_action_ = kContinue; 2218 resume_action_ = kContinue;
2182 stepping_fp_ = 0; 2219 stepping_fp_ = 0;
2183 isolate_->set_single_step(false); 2220 isolate_->set_single_step(false);
2184 ASSERT(!IsPaused()); 2221 ASSERT(!IsPaused());
2185 ASSERT(obj_cache_ == NULL); 2222 ASSERT(obj_cache_ == NULL);
2186 DebuggerEvent event(kBreakpointReached); 2223 DebuggerEvent event(DebuggerEvent::kBreakpointReached);
2187 event.top_frame = top_frame; 2224 event.set_top_frame(top_frame);
2188 event.breakpoint = bpt; 2225 event.set_breakpoint(bpt);
2189 Pause(&event); 2226 Pause(&event);
2190 } 2227 }
2191 2228
2192 2229
2193 void Debugger::DebuggerStepCallback() { 2230 void Debugger::DebuggerStepCallback() {
2194 ASSERT(isolate_->single_step()); 2231 ASSERT(isolate_->single_step());
2195 // We can't get here unless the debugger event handler enabled 2232 // We can't get here unless the debugger event handler enabled
2196 // single stepping. 2233 // single stepping.
2197 ASSERT(event_handler_ != NULL); 2234 ASSERT(event_handler_ != NULL);
2198 // Don't pause recursively. 2235 // Don't pause recursively.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 return; 2327 return;
2291 } 2328 }
2292 isolate_ = isolate; 2329 isolate_ = isolate;
2293 // Use the isolate's control port as the isolate_id for debugging. 2330 // Use the isolate's control port as the isolate_id for debugging.
2294 // This port will be used as a unique ID to represet the isolate in the 2331 // This port will be used as a unique ID to represet the isolate in the
2295 // debugger wire protocol messages. 2332 // debugger wire protocol messages.
2296 isolate_id_ = isolate->main_port(); 2333 isolate_id_ = isolate->main_port();
2297 initialized_ = true; 2334 initialized_ = true;
2298 2335
2299 // Signal isolate creation event. 2336 // Signal isolate creation event.
2300 SignalIsolateEvent(Debugger::kIsolateCreated); 2337 SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
2301 } 2338 }
2302 2339
2303 2340
2304 // Return innermost closure contained in 'function' that contains 2341 // Return innermost closure contained in 'function' that contains
2305 // the given token position. 2342 // the given token position.
2306 RawFunction* Debugger::FindInnermostClosure(const Function& function, 2343 RawFunction* Debugger::FindInnermostClosure(const Function& function,
2307 intptr_t token_pos) { 2344 intptr_t token_pos) {
2308 const Class& owner = Class::Handle(isolate_, function.Owner()); 2345 const Class& owner = Class::Handle(isolate_, function.Owner());
2309 if (owner.closures() == GrowableObjectArray::null()) { 2346 if (owner.closures() == GrowableObjectArray::null()) {
2310 return Function::null(); 2347 return Function::null();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 } 2570 }
2534 2571
2535 2572
2536 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2573 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2537 ASSERT(bpt->next() == NULL); 2574 ASSERT(bpt->next() == NULL);
2538 bpt->set_next(code_breakpoints_); 2575 bpt->set_next(code_breakpoints_);
2539 code_breakpoints_ = bpt; 2576 code_breakpoints_ = bpt;
2540 } 2577 }
2541 2578
2542 } // namespace dart 2579 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698