OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library debugger_page_element; | 5 library debugger_page_element; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:svg'; | 8 import 'dart:svg'; |
9 import 'dart:html'; | 9 import 'dart:html'; |
10 import 'dart:math'; | 10 import 'dart:math'; |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
597 'break-on-exception': [ | 597 'break-on-exception': [ |
598 _boeValues, | 598 _boeValues, |
599 _setBreakOnException, | 599 _setBreakOnException, |
600 (debugger, _) => debugger.breakOnException | 600 (debugger, _) => debugger.breakOnException |
601 ], | 601 ], |
602 'up-is-down': [ | 602 'up-is-down': [ |
603 _boolValues, | 603 _boolValues, |
604 _setUpIsDown, | 604 _setUpIsDown, |
605 (debugger, _) => debugger.upIsDown | 605 (debugger, _) => debugger.upIsDown |
606 ], | 606 ], |
607 'sane-async-stacks': [ | |
rmacnak
2017/02/08 18:34:18
"causal" to match the vm flag
Cutch
2017/02/09 22:45:50
Done.
| |
608 _boolValues, | |
609 _setSaneAsyncStacks, | |
610 (debugger, _) => debugger.saneAsyncStacks | |
611 ], | |
607 }; | 612 }; |
608 | 613 |
609 static Future _setBreakOnException(debugger, name, value) async { | 614 static Future _setBreakOnException(debugger, name, value) async { |
610 var result = await debugger.isolate.setExceptionPauseMode(value); | 615 var result = await debugger.isolate.setExceptionPauseMode(value); |
611 if (result.isError) { | 616 if (result.isError) { |
612 debugger.console.print(result.toString()); | 617 debugger.console.print(result.toString()); |
613 } else { | 618 } else { |
614 // Printing will occur elsewhere. | 619 // Printing will occur elsewhere. |
615 debugger.breakOnException = value; | 620 debugger.breakOnException = value; |
616 } | 621 } |
617 } | 622 } |
618 | 623 |
619 static Future _setUpIsDown(debugger, name, value) async { | 624 static Future _setUpIsDown(debugger, name, value) async { |
620 if (value == 'true') { | 625 if (value == 'true') { |
621 debugger.upIsDown = true; | 626 debugger.upIsDown = true; |
622 } else { | 627 } else { |
623 debugger.upIsDown = false; | 628 debugger.upIsDown = false; |
624 } | 629 } |
625 debugger.console.print('${name} = ${value}'); | 630 debugger.console.print('${name} = ${value}'); |
626 } | 631 } |
627 | 632 |
633 static Future _setSaneAsyncStacks(debugger, name, value) async { | |
634 if (value == 'true') { | |
635 debugger.saneAsyncStacks = true; | |
636 } else { | |
637 debugger.saneAsyncStacks = false; | |
638 } | |
639 debugger.refreshStack(); | |
640 debugger.console.print('${name} = ${value}'); | |
641 } | |
642 | |
628 Future run(List<String> args) async { | 643 Future run(List<String> args) async { |
629 if (args.length == 0) { | 644 if (args.length == 0) { |
630 for (var name in _options.keys) { | 645 for (var name in _options.keys) { |
631 var getHandler = _options[name][2]; | 646 var getHandler = _options[name][2]; |
632 var value = await getHandler(debugger, name); | 647 var value = await getHandler(debugger, name); |
633 debugger.console.print("${name} = ${value}"); | 648 debugger.console.print("${name} = ${value}"); |
634 } | 649 } |
635 } else if (args.length == 1) { | 650 } else if (args.length == 1) { |
636 var name = args[0].trim(); | 651 var name = args[0].trim(); |
637 var optionInfo = _options[name]; | 652 var optionInfo = _options[name]; |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1374 int _currentFrame = null; | 1389 int _currentFrame = null; |
1375 | 1390 |
1376 bool get upIsDown => _upIsDown; | 1391 bool get upIsDown => _upIsDown; |
1377 void set upIsDown(bool value) { | 1392 void set upIsDown(bool value) { |
1378 settings.set('up-is-down', value); | 1393 settings.set('up-is-down', value); |
1379 _upIsDown = value; | 1394 _upIsDown = value; |
1380 } | 1395 } |
1381 | 1396 |
1382 bool _upIsDown; | 1397 bool _upIsDown; |
1383 | 1398 |
1399 bool get saneAsyncStacks => _saneAsyncStacks; | |
1400 void set saneAsyncStacks(bool value) { | |
1401 settings.set('sane-async-stacks', value); | |
1402 _saneAsyncStacks = value; | |
1403 } | |
1404 | |
1405 bool _saneAsyncStacks; | |
1406 | |
1407 static const String kAsyncCausalStackFrames = 'asyncCausalFrames'; | |
1408 static const String kStackFrames = 'frames'; | |
1409 | |
1384 void upFrame(int count) { | 1410 void upFrame(int count) { |
1385 if (_upIsDown) { | 1411 if (_upIsDown) { |
1386 currentFrame += count; | 1412 currentFrame += count; |
1387 } else { | 1413 } else { |
1388 currentFrame -= count; | 1414 currentFrame -= count; |
1389 } | 1415 } |
1390 } | 1416 } |
1391 | 1417 |
1392 void downFrame(int count) { | 1418 void downFrame(int count) { |
1393 if (_upIsDown) { | 1419 if (_upIsDown) { |
1394 currentFrame -= count; | 1420 currentFrame -= count; |
1395 } else { | 1421 } else { |
1396 currentFrame += count; | 1422 currentFrame += count; |
1397 } | 1423 } |
1398 } | 1424 } |
1399 | 1425 |
1400 int get stackDepth => stack['frames'].length; | 1426 int get stackDepth { |
1427 if (saneAsyncStacks) { | |
1428 var asyncCausalStackFrames = stack[kAsyncCausalStackFrames]; | |
1429 var stackFrames = stack[kStackFrames]; | |
1430 if (asyncCausalStackFrames == null) { | |
1431 // No causal frames. | |
1432 return stackFrames.length; | |
1433 } | |
1434 return asyncCausalStackFrames.length; | |
1435 } else { | |
1436 return stack[kStackFrames].length; | |
1437 } | |
1438 } | |
1439 | |
1440 List get stackFrames { | |
1441 if (saneAsyncStacks) { | |
1442 var asyncCausalStackFrames = stack[kAsyncCausalStackFrames]; | |
1443 var stackFrames = stack[kStackFrames]; | |
1444 if (asyncCausalStackFrames == null) { | |
1445 // No causal frames. | |
1446 return stackFrames ?? []; | |
1447 } | |
1448 return asyncCausalStackFrames; | |
1449 } else { | |
1450 return stack[kStackFrames] ?? []; | |
1451 } | |
1452 } | |
1401 | 1453 |
1402 static final _history = ['']; | 1454 static final _history = ['']; |
1403 | 1455 |
1404 ObservatoryDebugger(this.isolate) { | 1456 ObservatoryDebugger(this.isolate) { |
1405 _loadSettings(); | 1457 _loadSettings(); |
1406 cmd = new RootCommand([ | 1458 cmd = new RootCommand([ |
1407 new AsyncNextCommand(this), | 1459 new AsyncNextCommand(this), |
1408 new BreakCommand(this), | 1460 new BreakCommand(this), |
1409 new ClearCommand(this), | 1461 new ClearCommand(this), |
1410 new ClsCommand(this), | 1462 new ClsCommand(this), |
(...skipping 16 matching lines...) Expand all Loading... | |
1427 new StepCommand(this), | 1479 new StepCommand(this), |
1428 new SyncNextCommand(this), | 1480 new SyncNextCommand(this), |
1429 new UpCommand(this), | 1481 new UpCommand(this), |
1430 new VmCommand(this), | 1482 new VmCommand(this), |
1431 ], _history); | 1483 ], _history); |
1432 _consolePrinter = new _ConsoleStreamPrinter(this); | 1484 _consolePrinter = new _ConsoleStreamPrinter(this); |
1433 } | 1485 } |
1434 | 1486 |
1435 void _loadSettings() { | 1487 void _loadSettings() { |
1436 _upIsDown = settings.get('up-is-down'); | 1488 _upIsDown = settings.get('up-is-down'); |
1489 _saneAsyncStacks = settings.get('sane-async-stacks') ?? true; | |
1437 } | 1490 } |
1438 | 1491 |
1439 S.VM get vm => page.app.vm; | 1492 S.VM get vm => page.app.vm; |
1440 | 1493 |
1441 void init() { | 1494 void init() { |
1442 console.printBold('Debugging isolate isolate ${isolate.number} ' | 1495 console.printBold('Debugging isolate isolate ${isolate.number} ' |
1443 '\'${isolate.name}\' '); | 1496 '\'${isolate.name}\' '); |
1444 console.printBold('Type \'h\' for help'); | 1497 console.printBold('Type \'h\' for help'); |
1445 // Wait a bit and if polymer still hasn't set up the isolate, | 1498 // Wait a bit and if polymer still hasn't set up the isolate, |
1446 // report this to the user. | 1499 // report this to the user. |
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2250 li.classes.add('list-group-item'); | 2303 li.classes.add('list-group-item'); |
2251 li.children.insert(0, messageElement); | 2304 li.children.insert(0, messageElement); |
2252 | 2305 |
2253 messageList.add(li); | 2306 messageList.add(li); |
2254 } | 2307 } |
2255 | 2308 |
2256 ObservatoryApplication get app => ObservatoryApplication.app; | 2309 ObservatoryApplication get app => ObservatoryApplication.app; |
2257 | 2310 |
2258 void updateStackFrames(S.ServiceMap newStack) { | 2311 void updateStackFrames(S.ServiceMap newStack) { |
2259 List frameElements = _frameList.children; | 2312 List frameElements = _frameList.children; |
2260 List newFrames = newStack['frames']; | 2313 List newFrames; |
2314 if (_debugger.saneAsyncStacks && | |
2315 (newStack[ObservatoryDebugger.kAsyncCausalStackFrames] != null)) { | |
2316 newFrames = newStack[ObservatoryDebugger.kAsyncCausalStackFrames]; | |
2317 } else { | |
2318 newFrames = newStack[ObservatoryDebugger.kStackFrames]; | |
2319 } | |
2261 | 2320 |
2262 // Remove any frames whose functions don't match, starting from | 2321 // Remove any frames whose functions don't match, starting from |
2263 // bottom of stack. | 2322 // bottom of stack. |
2264 int oldPos = frameElements.length - 1; | 2323 int oldPos = frameElements.length - 1; |
2265 int newPos = newFrames.length - 1; | 2324 int newPos = newFrames.length - 1; |
2266 while (oldPos >= 0 && newPos >= 0) { | 2325 while (oldPos >= 0 && newPos >= 0) { |
2267 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { | 2326 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { |
2268 // The rest of the frame elements no longer match. Remove them. | 2327 // The rest of the frame elements no longer match. Remove them. |
2269 for (int i = 0; i <= oldPos; i++) { | 2328 for (int i = 0; i <= oldPos; i++) { |
2270 // NOTE(turnidge): removeRange is missing, sadly. | 2329 // NOTE(turnidge): removeRange is missing, sadly. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2378 | 2437 |
2379 // Is this the current frame? | 2438 // Is this the current frame? |
2380 bool _current = false; | 2439 bool _current = false; |
2381 | 2440 |
2382 // Has this frame been pinned open? | 2441 // Has this frame been pinned open? |
2383 bool _pinned = false; | 2442 bool _pinned = false; |
2384 | 2443 |
2385 bool _expanded = false; | 2444 bool _expanded = false; |
2386 | 2445 |
2387 void setCurrent(bool value) { | 2446 void setCurrent(bool value) { |
2388 _frame.function.load().then((func) { | 2447 Future load = |
2448 (_frame.function != null) ? | |
2449 _frame.function.load() : | |
2450 new Future.value(null); | |
2451 load.then((func) { | |
2389 _current = value; | 2452 _current = value; |
2390 if (_current) { | 2453 if (_current) { |
2391 _expand(); | 2454 _expand(); |
2392 scrollIntoView(); | 2455 scrollIntoView(); |
2393 } else { | 2456 } else { |
2394 if (_pinned) { | 2457 if (_pinned) { |
2395 _expand(); | 2458 _expand(); |
2396 } else { | 2459 } else { |
2397 _unexpand(); | 2460 _unexpand(); |
2398 } | 2461 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2431 if (_pinned) { | 2494 if (_pinned) { |
2432 classes.add('shadow'); | 2495 classes.add('shadow'); |
2433 } else { | 2496 } else { |
2434 classes.remove('shadow'); | 2497 classes.remove('shadow'); |
2435 } | 2498 } |
2436 if (_current) { | 2499 if (_current) { |
2437 classes.add('current'); | 2500 classes.add('current'); |
2438 } else { | 2501 } else { |
2439 classes.remove('current'); | 2502 classes.remove('current'); |
2440 } | 2503 } |
2504 if ((_frame.kind == M.FrameKind.asyncSuspensionMarker) || | |
2505 (_frame.kind == M.FrameKind.asyncCausal)) { | |
2506 classes.add('causalFrame'); | |
2507 } | |
2508 if (_frame.kind == M.FrameKind.asyncSuspensionMarker) { | |
2509 final content = <Element>[ | |
2510 new SpanElement() | |
2511 ..children = _createMarkerHeader(_frame.marker) | |
2512 ]; | |
2513 children = content; | |
2514 return; | |
2515 } | |
2441 ButtonElement expandButton; | 2516 ButtonElement expandButton; |
2442 final content = <Element>[ | 2517 final content = <Element>[ |
2443 expandButton = new ButtonElement() | 2518 expandButton = new ButtonElement() |
2444 ..children = _createHeader() | 2519 ..children = _createHeader() |
2445 ..onClick.listen((e) async { | 2520 ..onClick.listen((e) async { |
2446 if (e.target is AnchorElement) { | 2521 if (e.target is AnchorElement) { |
2447 return; | 2522 return; |
2448 } | 2523 } |
2449 expandButton.disabled = true; | 2524 expandButton.disabled = true; |
2450 await _toggleExpand(); | 2525 await _toggleExpand(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2533 collapseButton.disabled = false; | 2608 collapseButton.disabled = false; |
2534 }) | 2609 }) |
2535 ..children = [iconExpandLess.clone(true)] | 2610 ..children = [iconExpandLess.clone(true)] |
2536 ] | 2611 ] |
2537 ] | 2612 ] |
2538 ]); | 2613 ]); |
2539 } | 2614 } |
2540 children = content; | 2615 children = content; |
2541 } | 2616 } |
2542 | 2617 |
2618 List<Element> _createMarkerHeader(String marker) { | |
2619 final content = [ | |
2620 new DivElement() | |
2621 ..classes = ['frameSummaryText'] | |
2622 ..children = [ | |
2623 new DivElement() | |
2624 ..classes = ['frameId'] | |
2625 ..text = 'Frame ${_frame.index}', | |
2626 new SpanElement()..text = '$marker', | |
2627 ] | |
2628 ]; | |
2629 return [ | |
2630 new DivElement() | |
2631 ..classes = ['frameSummary'] | |
2632 ..children = content | |
2633 ]; | |
2634 } | |
2635 | |
2543 List<Element> _createHeader() { | 2636 List<Element> _createHeader() { |
2544 final content = [ | 2637 final content = [ |
2545 new DivElement() | 2638 new DivElement() |
2546 ..classes = ['frameSummaryText'] | 2639 ..classes = ['frameSummaryText'] |
2547 ..children = [ | 2640 ..children = [ |
2548 new DivElement() | 2641 new DivElement() |
2549 ..classes = ['frameId'] | 2642 ..classes = ['frameId'] |
2550 ..text = 'Frame ${_frame.index}', | 2643 ..text = 'Frame ${_frame.index}', |
2551 new SpanElement() | 2644 new SpanElement() |
2552 ..children = _frame.function == null | 2645 ..children = _frame.function == null |
(...skipping 24 matching lines...) Expand all Loading... | |
2577 ..classes = ['frameSummary'] | 2670 ..classes = ['frameSummary'] |
2578 ..children = content | 2671 ..children = content |
2579 ]; | 2672 ]; |
2580 } | 2673 } |
2581 | 2674 |
2582 String makeExpandKey(String key) { | 2675 String makeExpandKey(String key) { |
2583 return '${_frame.function.qualifiedName}/${key}'; | 2676 return '${_frame.function.qualifiedName}/${key}'; |
2584 } | 2677 } |
2585 | 2678 |
2586 bool matchFrame(S.Frame newFrame) { | 2679 bool matchFrame(S.Frame newFrame) { |
2680 if (newFrame.kind != _frame.kind) { | |
2681 return false; | |
2682 } | |
2683 if (newFrame.function == null) { | |
2684 return frame.function == null; | |
2685 } | |
2587 return (newFrame.function.id == _frame.function.id && | 2686 return (newFrame.function.id == _frame.function.id && |
2588 newFrame.location.script.id == | 2687 newFrame.location.script.id == |
2589 frame.location.script.id); | 2688 frame.location.script.id); |
2590 } | 2689 } |
2591 | 2690 |
2592 void updateFrame(S.Frame newFrame) { | 2691 void updateFrame(S.Frame newFrame) { |
2593 assert(matchFrame(newFrame)); | 2692 assert(matchFrame(newFrame)); |
2594 _frame = newFrame; | 2693 _frame = newFrame; |
2595 } | 2694 } |
2596 | 2695 |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3263 ..setAttribute('height', '24') | 3362 ..setAttribute('height', '24') |
3264 ..children = [ | 3363 ..children = [ |
3265 new PathElement() | 3364 new PathElement() |
3266 ..setAttribute( | 3365 ..setAttribute( |
3267 'd', | 3366 'd', |
3268 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' | 3367 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' |
3269 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' | 3368 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' |
3270 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' | 3369 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' |
3271 '9h2V7h-2v2z') | 3370 '9h2V7h-2v2z') |
3272 ]; | 3371 ]; |
OLD | NEW |