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

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

Issue 1699153002: Add step OverAwait to service protocol (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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 "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 } 211 }
212 } 212 }
213 213
214 214
215 void Breakpoint::PrintJSON(JSONStream* stream) { 215 void Breakpoint::PrintJSON(JSONStream* stream) {
216 JSONObject jsobj(stream); 216 JSONObject jsobj(stream);
217 jsobj.AddProperty("type", "Breakpoint"); 217 jsobj.AddProperty("type", "Breakpoint");
218 218
219 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id()); 219 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id());
220 jsobj.AddProperty("breakpointNumber", id()); 220 jsobj.AddProperty("breakpointNumber", id());
221 if (is_synthetic_async()) {
222 jsobj.AddProperty("isSyntheticAsyncBreakpoint", is_synthetic_async());
223 }
221 jsobj.AddProperty("resolved", bpt_location_->IsResolved()); 224 jsobj.AddProperty("resolved", bpt_location_->IsResolved());
222 if (bpt_location_->IsResolved()) { 225 if (bpt_location_->IsResolved()) {
223 jsobj.AddLocation(bpt_location_); 226 jsobj.AddLocation(bpt_location_);
224 } else { 227 } else {
225 jsobj.AddUnresolvedLocation(bpt_location_); 228 jsobj.AddUnresolvedLocation(bpt_location_);
226 } 229 }
227 } 230 }
228 231
229 232
230 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 233 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 if (bpt == NULL) { 426 if (bpt == NULL) {
424 bpt = new Breakpoint(dbg->nextId(), this); 427 bpt = new Breakpoint(dbg->nextId(), this);
425 bpt->SetIsSingleShot(); 428 bpt->SetIsSingleShot();
426 AddBreakpoint(bpt, dbg); 429 AddBreakpoint(bpt, dbg);
427 } 430 }
428 return bpt; 431 return bpt;
429 } 432 }
430 433
431 434
432 Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg, 435 Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg,
433 const Instance& closure) { 436 const Instance& closure,
437 bool for_over_await) {
434 Breakpoint* bpt = breakpoints(); 438 Breakpoint* bpt = breakpoints();
435 while (bpt != NULL) { 439 while (bpt != NULL) {
436 if (bpt->IsPerClosure() && bpt->closure() == closure.raw()) break; 440 if (bpt->IsPerClosure() && bpt->closure() == closure.raw()) break;
437 bpt = bpt->next(); 441 bpt = bpt->next();
438 } 442 }
439 if (bpt == NULL) { 443 if (bpt == NULL) {
440 bpt = new Breakpoint(dbg->nextId(), this); 444 bpt = new Breakpoint(dbg->nextId(), this);
441 bpt->SetIsPerClosure(closure); 445 bpt->SetIsPerClosure(closure);
446 bpt->set_is_synthetic_async(for_over_await);
442 AddBreakpoint(bpt, dbg); 447 AddBreakpoint(bpt, dbg);
443 } 448 }
444 return bpt; 449 return bpt;
445 } 450 }
446 451
447 452
448 const char* Debugger::QualifiedFunctionName(const Function& func) { 453 const char* Debugger::QualifiedFunctionName(const Function& func) {
449 const String& func_name = String::Handle(func.name()); 454 const String& func_name = String::Handle(func.name());
450 Class& func_class = Class::Handle(func.Owner()); 455 Class& func_class = Class::Handle(func.Owner());
451 String& class_name = String::Handle(func_class.Name()); 456 String& class_name = String::Handle(func_class.Name());
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 const String& fname) { 1324 const String& fname) {
1320 ASSERT(!library.IsNull()); 1325 ASSERT(!library.IsNull());
1321 const Object& object = Object::Handle(library.ResolveName(fname)); 1326 const Object& object = Object::Handle(library.ResolveName(fname));
1322 if (!object.IsNull() && object.IsFunction()) { 1327 if (!object.IsNull() && object.IsFunction()) {
1323 return Function::Cast(object).raw(); 1328 return Function::Cast(object).raw();
1324 } 1329 }
1325 return Function::null(); 1330 return Function::null();
1326 } 1331 }
1327 1332
1328 1333
1334 bool Debugger::SetupStepOverAwait() {
1335 ActivationFrame* top_frame = TopDartFrame();
1336 Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation());
1337 if (closure_or_null.IsNull()) {
1338 // Not at an async operation.
1339 return false;
1340 }
1341 // Add a break point at the async continuation closure.
1342 ASSERT(closure_or_null.IsInstance());
1343 ASSERT(Instance::Cast(closure_or_null).IsClosure());
1344 Breakpoint* bpt =
1345 SetBreakpointAtActivation(Instance::Cast(closure_or_null), true);
1346 if (bpt == NULL) {
1347 // Unable to set the breakpoint.
1348 return false;
1349 }
1350 return true;
1351 }
1352
1353
1329 void Debugger::SetSingleStep() { 1354 void Debugger::SetSingleStep() {
1330 resume_action_ = kSingleStep; 1355 resume_action_ = kSingleStep;
1331 } 1356 }
1332 1357
1333 1358
1334 void Debugger::SetStepOver() { 1359 void Debugger::SetStepOver() {
1335 resume_action_ = kStepOver; 1360 resume_action_ = kStepOver;
1336 } 1361 }
1337 1362
1338 1363
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 target_function.end_token_pos(), 2173 target_function.end_token_pos(),
2149 -1, -1 /* no requested line/col */); 2174 -1, -1 /* no requested line/col */);
2150 if (single_shot) { 2175 if (single_shot) {
2151 return bpt_location->AddSingleShot(this); 2176 return bpt_location->AddSingleShot(this);
2152 } else { 2177 } else {
2153 return bpt_location->AddRepeated(this); 2178 return bpt_location->AddRepeated(this);
2154 } 2179 }
2155 } 2180 }
2156 2181
2157 2182
2158 Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure) { 2183 Breakpoint* Debugger::SetBreakpointAtActivation(
2184 const Instance& closure, bool for_over_await) {
2159 if (!closure.IsClosure()) { 2185 if (!closure.IsClosure()) {
2160 return NULL; 2186 return NULL;
2161 } 2187 }
2162 const Function& func = Function::Handle(Closure::Cast(closure).function()); 2188 const Function& func = Function::Handle(Closure::Cast(closure).function());
2163 const Script& script = Script::Handle(func.script()); 2189 const Script& script = Script::Handle(func.script());
2164 BreakpointLocation* bpt_location = SetBreakpoint(script, 2190 BreakpointLocation* bpt_location = SetBreakpoint(script,
2165 func.token_pos(), 2191 func.token_pos(),
2166 func.end_token_pos(), 2192 func.end_token_pos(),
2167 -1, -1 /* no line/col */); 2193 -1, -1 /* no line/col */);
2168 return bpt_location->AddPerClosure(this, closure); 2194 return bpt_location->AddPerClosure(this, closure, for_over_await);
2169 } 2195 }
2170 2196
2171 2197
2172 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) { 2198 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) {
2173 if (!closure.IsClosure()) { 2199 if (!closure.IsClosure()) {
2174 return NULL; 2200 return NULL;
2175 } 2201 }
2176 2202
2177 BreakpointLocation* loc = breakpoint_locations_; 2203 BreakpointLocation* loc = breakpoint_locations_;
2178 while (loc != NULL) { 2204 while (loc != NULL) {
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 } 2783 }
2758 bpt = bpt->next(); 2784 bpt = bpt->next();
2759 } 2785 }
2760 } 2786 }
2761 } 2787 }
2762 2788
2763 if (bpt_hit == NULL) { 2789 if (bpt_hit == NULL) {
2764 return Error::null(); 2790 return Error::null();
2765 } 2791 }
2766 2792
2793 if (bpt_hit->is_synthetic_async()) {
2794 DebuggerStackTrace* stack_trace = CollectStackTrace();
2795 ASSERT(stack_trace->Length() > 0);
2796 ASSERT(stack_trace_ == NULL);
2797 stack_trace_ = stack_trace;
2798
2799 // Hit a synthetic async breakpoint.
2800 if (FLAG_verbose_debug) {
2801 OS::Print(">>> hit synthetic breakpoint at %s:%" Pd " "
2802 "(token %s) (address %#" Px ")\n",
2803 String::Handle(cbpt->SourceUrl()).ToCString(),
2804 cbpt->LineNumber(),
2805 cbpt->token_pos().ToCString(),
2806 top_frame->pc());
2807 }
2808
2809 RemoveBreakpoint(bpt_hit->id());
2810 bpt_hit = NULL;
rmacnak 2016/02/16 21:21:58 It would clearer from the client's perspective if
Cutch 2016/02/17 18:24:21 Done.
2811
2812 // We are at the entry of an async function.
2813 // We issue a step over to resume at the point after the await statement.
2814 SetStepOver();
2815 // When we single step from a user breakpoint, our next stepping
2816 // point will be at the exact same pc. Skip it.
2817 HandleSteppingRequest(stack_trace_, true /* skip next step */);
2818 stack_trace_ = NULL;
2819 return Error::null();
2820 }
2821
2767 if (FLAG_verbose_debug) { 2822 if (FLAG_verbose_debug) {
2768 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " 2823 OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
2769 "(token %s) (address %#" Px ")\n", 2824 "(token %s) (address %#" Px ")\n",
2770 cbpt->IsInternal() ? "internal" : "user", 2825 cbpt->IsInternal() ? "internal" : "user",
2771 String::Handle(cbpt->SourceUrl()).ToCString(), 2826 String::Handle(cbpt->SourceUrl()).ToCString(),
2772 cbpt->LineNumber(), 2827 cbpt->LineNumber(),
2773 cbpt->token_pos().ToCString(), 2828 cbpt->token_pos().ToCString(),
2774 top_frame->pc()); 2829 top_frame->pc());
2775 } 2830 }
2776 2831
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
3274 3329
3275 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 3330 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3276 ASSERT(bpt->next() == NULL); 3331 ASSERT(bpt->next() == NULL);
3277 bpt->set_next(code_breakpoints_); 3332 bpt->set_next(code_breakpoints_);
3278 code_breakpoints_ = bpt; 3333 code_breakpoints_ = bpt;
3279 } 3334 }
3280 3335
3281 #endif // !PRODUCT 3336 #endif // !PRODUCT
3282 3337
3283 } // namespace dart 3338 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698