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 'causal-async-stacks': [ |
| 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('causal-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('causal-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 |