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': [ |
| 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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2244 li.classes.add('list-group-item'); | 2297 li.classes.add('list-group-item'); |
2245 li.children.insert(0, messageElement); | 2298 li.children.insert(0, messageElement); |
2246 | 2299 |
2247 messageList.add(li); | 2300 messageList.add(li); |
2248 } | 2301 } |
2249 | 2302 |
2250 ObservatoryApplication get app => ObservatoryApplication.app; | 2303 ObservatoryApplication get app => ObservatoryApplication.app; |
2251 | 2304 |
2252 void updateStackFrames(S.ServiceMap newStack) { | 2305 void updateStackFrames(S.ServiceMap newStack) { |
2253 List frameElements = _frameList.children; | 2306 List frameElements = _frameList.children; |
2254 List newFrames = newStack['frames']; | 2307 List newFrames; |
| 2308 if (_debugger.saneAsyncStacks && |
| 2309 (newStack[ObservatoryDebugger.kAsyncCausalStackFrames] != null)) { |
| 2310 newFrames = newStack[ObservatoryDebugger.kAsyncCausalStackFrames]; |
| 2311 } else { |
| 2312 newFrames = newStack[ObservatoryDebugger.kStackFrames]; |
| 2313 } |
2255 | 2314 |
2256 // Remove any frames whose functions don't match, starting from | 2315 // Remove any frames whose functions don't match, starting from |
2257 // bottom of stack. | 2316 // bottom of stack. |
2258 int oldPos = frameElements.length - 1; | 2317 int oldPos = frameElements.length - 1; |
2259 int newPos = newFrames.length - 1; | 2318 int newPos = newFrames.length - 1; |
2260 while (oldPos >= 0 && newPos >= 0) { | 2319 while (oldPos >= 0 && newPos >= 0) { |
2261 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { | 2320 if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) { |
2262 // The rest of the frame elements no longer match. Remove them. | 2321 // The rest of the frame elements no longer match. Remove them. |
2263 for (int i = 0; i <= oldPos; i++) { | 2322 for (int i = 0; i <= oldPos; i++) { |
2264 // NOTE(turnidge): removeRange is missing, sadly. | 2323 // NOTE(turnidge): removeRange is missing, sadly. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 | 2431 |
2373 // Is this the current frame? | 2432 // Is this the current frame? |
2374 bool _current = false; | 2433 bool _current = false; |
2375 | 2434 |
2376 // Has this frame been pinned open? | 2435 // Has this frame been pinned open? |
2377 bool _pinned = false; | 2436 bool _pinned = false; |
2378 | 2437 |
2379 bool _expanded = false; | 2438 bool _expanded = false; |
2380 | 2439 |
2381 void setCurrent(bool value) { | 2440 void setCurrent(bool value) { |
2382 _frame.function.load().then((func) { | 2441 Future load = |
| 2442 (_frame.function != null) ? |
| 2443 _frame.function.load() : |
| 2444 new Future.value(null); |
| 2445 load.then((func) { |
2383 _current = value; | 2446 _current = value; |
2384 if (_current) { | 2447 if (_current) { |
2385 _expand(); | 2448 _expand(); |
2386 scrollIntoView(); | 2449 scrollIntoView(); |
2387 } else { | 2450 } else { |
2388 if (_pinned) { | 2451 if (_pinned) { |
2389 _expand(); | 2452 _expand(); |
2390 } else { | 2453 } else { |
2391 _unexpand(); | 2454 _unexpand(); |
2392 } | 2455 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 if (_pinned) { | 2488 if (_pinned) { |
2426 classes.add('shadow'); | 2489 classes.add('shadow'); |
2427 } else { | 2490 } else { |
2428 classes.remove('shadow'); | 2491 classes.remove('shadow'); |
2429 } | 2492 } |
2430 if (_current) { | 2493 if (_current) { |
2431 classes.add('current'); | 2494 classes.add('current'); |
2432 } else { | 2495 } else { |
2433 classes.remove('current'); | 2496 classes.remove('current'); |
2434 } | 2497 } |
| 2498 if ((_frame.kind == M.FrameKind.asyncSuspensionMarker) || |
| 2499 (_frame.kind == M.FrameKind.asyncCausal)) { |
| 2500 classes.add('causalFrame'); |
| 2501 } |
| 2502 if (_frame.kind == M.FrameKind.asyncSuspensionMarker) { |
| 2503 final content = <Element>[ |
| 2504 new SpanElement() |
| 2505 ..children = _createMarkerHeader(_frame.marker) |
| 2506 ]; |
| 2507 children = content; |
| 2508 return; |
| 2509 } |
2435 ButtonElement expandButton; | 2510 ButtonElement expandButton; |
2436 final content = <Element>[ | 2511 final content = <Element>[ |
2437 expandButton = new ButtonElement() | 2512 expandButton = new ButtonElement() |
2438 ..children = _createHeader() | 2513 ..children = _createHeader() |
2439 ..onClick.listen((e) async { | 2514 ..onClick.listen((e) async { |
2440 if (e.target is AnchorElement) { | 2515 if (e.target is AnchorElement) { |
2441 return; | 2516 return; |
2442 } | 2517 } |
2443 expandButton.disabled = true; | 2518 expandButton.disabled = true; |
2444 await _toggleExpand(); | 2519 await _toggleExpand(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2527 collapseButton.disabled = false; | 2602 collapseButton.disabled = false; |
2528 }) | 2603 }) |
2529 ..children = [iconExpandLess.clone(true)] | 2604 ..children = [iconExpandLess.clone(true)] |
2530 ] | 2605 ] |
2531 ] | 2606 ] |
2532 ]); | 2607 ]); |
2533 } | 2608 } |
2534 children = content; | 2609 children = content; |
2535 } | 2610 } |
2536 | 2611 |
| 2612 List<Element> _createMarkerHeader(String marker) { |
| 2613 final content = [ |
| 2614 new DivElement() |
| 2615 ..classes = ['frameSummaryText'] |
| 2616 ..children = [ |
| 2617 new DivElement() |
| 2618 ..classes = ['frameId'] |
| 2619 ..text = 'Frame ${_frame.index}', |
| 2620 new SpanElement()..text = '$marker', |
| 2621 ] |
| 2622 ]; |
| 2623 return [ |
| 2624 new DivElement() |
| 2625 ..classes = ['frameSummary'] |
| 2626 ..children = content |
| 2627 ]; |
| 2628 } |
| 2629 |
2537 List<Element> _createHeader() { | 2630 List<Element> _createHeader() { |
2538 final content = [ | 2631 final content = [ |
2539 new DivElement() | 2632 new DivElement() |
2540 ..classes = ['frameSummaryText'] | 2633 ..classes = ['frameSummaryText'] |
2541 ..children = [ | 2634 ..children = [ |
2542 new DivElement() | 2635 new DivElement() |
2543 ..classes = ['frameId'] | 2636 ..classes = ['frameId'] |
2544 ..text = 'Frame ${_frame.index}', | 2637 ..text = 'Frame ${_frame.index}', |
2545 new SpanElement() | 2638 new SpanElement() |
2546 ..children = _frame.function == null | 2639 ..children = _frame.function == null |
(...skipping 24 matching lines...) Expand all Loading... |
2571 ..classes = ['frameSummary'] | 2664 ..classes = ['frameSummary'] |
2572 ..children = content | 2665 ..children = content |
2573 ]; | 2666 ]; |
2574 } | 2667 } |
2575 | 2668 |
2576 String makeExpandKey(String key) { | 2669 String makeExpandKey(String key) { |
2577 return '${_frame.function.qualifiedName}/${key}'; | 2670 return '${_frame.function.qualifiedName}/${key}'; |
2578 } | 2671 } |
2579 | 2672 |
2580 bool matchFrame(S.Frame newFrame) { | 2673 bool matchFrame(S.Frame newFrame) { |
| 2674 if (newFrame.kind != _frame.kind) { |
| 2675 return false; |
| 2676 } |
| 2677 if (newFrame.function == null) { |
| 2678 return frame.function == null; |
| 2679 } |
2581 return (newFrame.function.id == _frame.function.id && | 2680 return (newFrame.function.id == _frame.function.id && |
2582 newFrame.location.script.id == | 2681 newFrame.location.script.id == |
2583 frame.location.script.id); | 2682 frame.location.script.id); |
2584 } | 2683 } |
2585 | 2684 |
2586 void updateFrame(S.Frame newFrame) { | 2685 void updateFrame(S.Frame newFrame) { |
2587 assert(matchFrame(newFrame)); | 2686 assert(matchFrame(newFrame)); |
2588 _frame = newFrame; | 2687 _frame = newFrame; |
2589 } | 2688 } |
2590 | 2689 |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 ..setAttribute('height', '24') | 3356 ..setAttribute('height', '24') |
3258 ..children = [ | 3357 ..children = [ |
3259 new PathElement() | 3358 new PathElement() |
3260 ..setAttribute( | 3359 ..setAttribute( |
3261 'd', | 3360 'd', |
3262 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' | 3361 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' |
3263 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' | 3362 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' |
3264 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' | 3363 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' |
3265 '9h2V7h-2v2z') | 3364 '9h2V7h-2v2z') |
3266 ]; | 3365 ]; |
OLD | NEW |