OLD | NEW |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library dartino.vm_session; | 5 library dartino.vm_session; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'dart:typed_data' show | 9 import 'dart:typed_data' show |
10 ByteData; | 10 ByteData; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // TODO(sigurdm): for now only the stdio and stderr events are actually | 72 // TODO(sigurdm): for now only the stdio and stderr events are actually |
73 // notified. | 73 // notified. |
74 abstract class DebugListener { | 74 abstract class DebugListener { |
75 // Notification that a new process has started. | 75 // Notification that a new process has started. |
76 processStart(int processId) {} | 76 processStart(int processId) {} |
77 // Notification that a process is ready to run. | 77 // Notification that a process is ready to run. |
78 processRunnable(int processId) {} | 78 processRunnable(int processId) {} |
79 // Notification that a process has exited. | 79 // Notification that a process has exited. |
80 processExit(int processId) {} | 80 processExit(int processId) {} |
81 // A process has paused at start, before executing code. | 81 // A process has paused at start, before executing code. |
82 pauseStart(int processId, BackTraceFrame topframe) {} | 82 // This is sent on spawning processes. |
| 83 pauseStart(int processId) {} |
83 // An process has paused at exit, before terminating. | 84 // An process has paused at exit, before terminating. |
84 pauseExit(int processId, BackTraceFrame topframe) {} | 85 pauseExit(int processId, BackTraceFrame topFrame) {} |
85 // A process has paused at a breakpoint or due to stepping. | 86 // A process has paused at a breakpoint or due to stepping. |
86 pauseBreakpoint(int processId, BackTraceFrame topframe, int breakpointId) {} | 87 pauseBreakpoint( |
| 88 int processId, BackTraceFrame topFrame, Breakpoint breakpoint) {} |
87 // A process has paused due to interruption. | 89 // A process has paused due to interruption. |
88 pauseInterrupted(int processId, BackTraceFrame topframe) {} | 90 pauseInterrupted(int processId, BackTraceFrame topFrame) {} |
89 // A process has paused due to an exception. | 91 // A process has paused due to an exception. |
90 pauseException(int processId, BackTraceFrame topframe, RemoteObject thrown) {} | 92 pauseException(int processId, BackTraceFrame topFrame, RemoteObject thrown) {} |
91 // A process has started or resumed execution. | 93 // A process has started or resumed execution. |
92 resume(int processId) {} | 94 resume(int processId) {} |
93 // A breakpoint has been added for a process. | 95 // A breakpoint has been added for a process. |
94 breakpointAdded(int processId, Breakpoint breakpoint) {} | 96 breakpointAdded(int processId, Breakpoint breakpoint) {} |
95 // A breakpoint has been removed. | 97 // A breakpoint has been removed. |
96 breakpointRemoved(int processId, Breakpoint breakpoint) {} | 98 breakpointRemoved(int processId, Breakpoint breakpoint) {} |
97 // A garbage collection event. | 99 // A garbage collection event. |
98 gc(int processId) {} | 100 gc(int processId) {} |
99 // Notification of bytes written to stdout. | 101 // Notification of bytes written to stdout. |
100 writeStdOut(int processId, List<int> data) {} | 102 writeStdOut(int processId, List<int> data) {} |
101 // Notification of bytes written stderr. | 103 // Notification of bytes written stderr. |
102 writeStdErr(int processId, List<int> data) {} | 104 writeStdErr(int processId, List<int> data) {} |
103 // The connection to the vm was lost. | 105 // The connection to the vm was lost. |
104 lostConnection() {} | 106 lostConnection() {} |
| 107 // The debugged program is over. |
| 108 terminated() {} |
105 } | 109 } |
106 | 110 |
107 class SinkDebugListener extends DebugListener { | 111 class SinkDebugListener extends DebugListener { |
108 final Sink stdoutSink; | 112 final Sink stdoutSink; |
109 final Sink stderrSink; | 113 final Sink stderrSink; |
110 SinkDebugListener(this.stdoutSink, this.stderrSink); | 114 SinkDebugListener(this.stdoutSink, this.stderrSink); |
111 | 115 |
112 writeStdOut(int processId, List<int> data) { | 116 writeStdOut(int processId, List<int> data) { |
113 stdoutSink.add(data); | 117 stdoutSink.add(data); |
114 } | 118 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 while (!_drainedIncomingCommands) { | 300 while (!_drainedIncomingCommands) { |
297 VmCommand response = await readNextCommand(force: false); | 301 VmCommand response = await readNextCommand(force: false); |
298 if (!ignoreExtraCommands && response != null) { | 302 if (!ignoreExtraCommands && response != null) { |
299 await kill(); | 303 await kill(); |
300 throw new StateError( | 304 throw new StateError( |
301 "Got unexpected command from dartino-vm during shutdown " | 305 "Got unexpected command from dartino-vm during shutdown " |
302 "($response)"); | 306 "($response)"); |
303 } | 307 } |
304 } | 308 } |
305 vmState = VmState.terminated; | 309 vmState = VmState.terminated; |
| 310 listeners.forEach((DebugListener listener) { |
| 311 listener.terminated(); |
| 312 }); |
306 return connection.done; | 313 return connection.done; |
307 } | 314 } |
308 | 315 |
309 Future interrupt() { | 316 Future interrupt() { |
310 return sendCommand(const ProcessDebugInterrupt()); | 317 return sendCommand(const ProcessDebugInterrupt()); |
311 } | 318 } |
312 | 319 |
313 /// Closes the connection to the dartino-vm. It does not wait until it shuts | 320 /// Closes the connection to the dartino-vm. It does not wait until it shuts |
314 /// down. | 321 /// down. |
315 /// | 322 /// |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 VmCommand reply = await runCommand(const Debugging()); | 404 VmCommand reply = await runCommand(const Debugging()); |
398 if (reply == null || reply is! DebuggingReply) { | 405 if (reply == null || reply is! DebuggingReply) { |
399 throw new Exception("Expected a reply from the debugging command"); | 406 throw new Exception("Expected a reply from the debugging command"); |
400 } | 407 } |
401 return reply; | 408 return reply; |
402 } | 409 } |
403 | 410 |
404 Future spawnProcess(List<String> arguments) async { | 411 Future spawnProcess(List<String> arguments) async { |
405 await runCommand(new ProcessSpawnForMain(arguments)); | 412 await runCommand(new ProcessSpawnForMain(arguments)); |
406 vmState = VmState.spawned; | 413 vmState = VmState.spawned; |
| 414 listeners.forEach((DebugListener listener) { |
| 415 listener.pauseStart(0); |
| 416 listener.processRunnable(0); |
| 417 }); |
407 } | 418 } |
408 | 419 |
409 /// Returns the [NameOffsetMapping] stored in the '.info.json' adjacent to a | 420 /// Returns the [NameOffsetMapping] stored in the '.info.json' adjacent to a |
410 /// snapshot location. | 421 /// snapshot location. |
411 Future<NameOffsetMapping> getInfoFromSnapshotLocation(Uri snapshot) async { | 422 Future<NameOffsetMapping> getInfoFromSnapshotLocation(Uri snapshot) async { |
412 Uri info = snapshot.replace(path: "${snapshot.path}.info.json"); | 423 Uri info = snapshot.replace(path: "${snapshot.path}.info.json"); |
413 File infoFile = new File.fromUri(info); | 424 File infoFile = new File.fromUri(info); |
414 | 425 |
415 if (!await infoFile.exists()) { | 426 if (!await infoFile.exists()) { |
416 await shutdown(); | 427 await shutdown(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // This method handles the various responses a command can return to indicate | 506 // This method handles the various responses a command can return to indicate |
496 // the process has stopped running. | 507 // the process has stopped running. |
497 // The session's state is updated to match the current state of the vm. | 508 // The session's state is updated to match the current state of the vm. |
498 Future<VmCommand> handleProcessStop(VmCommand response) async { | 509 Future<VmCommand> handleProcessStop(VmCommand response) async { |
499 interactiveExitCode = exit_codes.COMPILER_EXITCODE_CRASH; | 510 interactiveExitCode = exit_codes.COMPILER_EXITCODE_CRASH; |
500 debugState.reset(); | 511 debugState.reset(); |
501 switch (response.code) { | 512 switch (response.code) { |
502 case VmCommandCode.UncaughtException: | 513 case VmCommandCode.UncaughtException: |
503 interactiveExitCode = exit_codes.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION; | 514 interactiveExitCode = exit_codes.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION; |
504 vmState = VmState.terminating; | 515 vmState = VmState.terminating; |
| 516 UncaughtException command = response; |
| 517 debugState.currentProcess = command.processId; |
| 518 var function = dartinoSystem.lookupFunctionById(command.functionId); |
| 519 debugState.topFrame = new BackTraceFrame( |
| 520 function, command.bytecodeIndex, compiler, debugState); |
| 521 RemoteObject thrown = await uncaughtException(); |
| 522 listeners.forEach((DebugListener listener) { |
| 523 listener.pauseException( |
| 524 debugState.currentProcess, debugState.topFrame, thrown); |
| 525 }); |
505 break; | 526 break; |
506 | 527 |
507 case VmCommandCode.ProcessCompileTimeError: | 528 case VmCommandCode.ProcessCompileTimeError: |
| 529 listeners.forEach((DebugListener listener) { |
| 530 listener.pauseException(0, null, null); // XXX |
| 531 }); |
508 interactiveExitCode = exit_codes.DART_VM_EXITCODE_COMPILE_TIME_ERROR; | 532 interactiveExitCode = exit_codes.DART_VM_EXITCODE_COMPILE_TIME_ERROR; |
509 vmState = VmState.terminating; | 533 vmState = VmState.terminating; |
510 break; | 534 break; |
511 | 535 |
512 case VmCommandCode.ProcessTerminated: | 536 case VmCommandCode.ProcessTerminated: |
513 interactiveExitCode = 0; | 537 interactiveExitCode = 0; |
514 vmState = VmState.terminating; | 538 listeners.forEach((DebugListener listener) { |
| 539 listener.processExit(0); // XXX |
| 540 }); |
515 break; | 541 break; |
516 | 542 |
517 case VmCommandCode.ConnectionError: | 543 case VmCommandCode.ConnectionError: |
518 interactiveExitCode = exit_codes.COMPILER_EXITCODE_CONNECTION_ERROR; | 544 interactiveExitCode = exit_codes.COMPILER_EXITCODE_CONNECTION_ERROR; |
519 vmState = VmState.terminating; | 545 vmState = VmState.terminating; |
520 await shutdown(); | 546 await shutdown(); |
| 547 listeners.forEach((DebugListener listener) { |
| 548 listener.lostConnection(); |
| 549 }); |
521 break; | 550 break; |
522 | 551 |
523 case VmCommandCode.ProcessBreakpoint: | 552 case VmCommandCode.ProcessBreakpoint: |
524 interactiveExitCode = 0; | 553 interactiveExitCode = 0; |
525 ProcessBreakpoint command = response; | 554 ProcessBreakpoint command = response; |
526 debugState.currentProcess = command.processId; | 555 debugState.currentProcess = command.processId; |
527 var function = dartinoSystem.lookupFunctionById(command.functionId); | 556 var function = dartinoSystem.lookupFunctionById(command.functionId); |
528 debugState.topFrame = new BackTraceFrame( | 557 debugState.topFrame = new BackTraceFrame( |
529 function, command.bytecodeIndex, compiler, debugState); | 558 function, command.bytecodeIndex, compiler, debugState); |
530 vmState = VmState.paused; | 559 vmState = VmState.paused; |
| 560 Breakpoint bp = debugState.breakpoints[command.breakpointId]; |
| 561 if (bp == null) { |
| 562 listeners.forEach((DebugListener listener) { |
| 563 listener.pauseInterrupted( |
| 564 command.processId, |
| 565 debugState.topFrame); |
| 566 }); |
| 567 } else { |
| 568 listeners.forEach((DebugListener listener) { |
| 569 listener.pauseBreakpoint( |
| 570 command.processId, |
| 571 debugState.topFrame, |
| 572 bp); |
| 573 }); |
| 574 } |
531 break; | 575 break; |
532 | 576 |
533 default: | 577 default: |
534 throw new StateError( | 578 throw new StateError( |
535 "Unhandled response from Dartino VM connection: ${response.code}"); | 579 "Unhandled response from Dartino VM connection: ${response.code}"); |
536 | 580 |
537 } | 581 } |
538 return response; | 582 return response; |
539 } | 583 } |
540 | 584 |
541 Future<VmCommand> startRunning() async { | 585 Future<VmCommand> startRunning() async { |
542 await sendCommand(const ProcessRun()); | 586 await sendCommand(const ProcessRun()); |
543 vmState = VmState.running; | 587 vmState = VmState.running; |
| 588 listeners.forEach((DebugListener listener) { |
| 589 listener.processStart(0); |
| 590 }); |
| 591 listeners.forEach((DebugListener listener) { |
| 592 listener.processRunnable(0); |
| 593 }); |
| 594 listeners.forEach((DebugListener listener) { |
| 595 listener.resume(0); |
| 596 }); |
544 return handleProcessStop(await readNextCommand()); | 597 return handleProcessStop(await readNextCommand()); |
545 } | 598 } |
546 | 599 |
547 Future setBreakpointHelper(String name, | 600 Future<Breakpoint> setBreakpointHelper(DartinoFunction function, |
548 DartinoFunction function, | |
549 int bytecodeIndex) async { | 601 int bytecodeIndex) async { |
550 ProcessSetBreakpoint response = await runCommands([ | 602 ProcessSetBreakpoint response = await runCommands([ |
551 new PushFromMap(MapId.methods, function.functionId), | 603 new PushFromMap(MapId.methods, function.functionId), |
552 new ProcessSetBreakpoint(bytecodeIndex), | 604 new ProcessSetBreakpoint(bytecodeIndex), |
553 ]); | 605 ]); |
554 int breakpointId = response.value; | 606 int breakpointId = response.value; |
555 var breakpoint = new Breakpoint(function, bytecodeIndex, breakpointId); | 607 Breakpoint breakpoint = |
| 608 new Breakpoint(function, bytecodeIndex, breakpointId); |
556 debugState.breakpoints[breakpointId] = breakpoint; | 609 debugState.breakpoints[breakpointId] = breakpoint; |
| 610 listeners.forEach( |
| 611 (DebugListener listener) => listener.breakpointAdded(0, breakpoint)); |
557 return breakpoint; | 612 return breakpoint; |
558 } | 613 } |
559 | 614 |
560 // TODO(ager): Let setBreakpoint return a stream instead and deal with | 615 // TODO(ager): Let setBreakpoint return a stream instead and deal with |
561 // error situations such as bytecode indices that are out of bounds for | 616 // error situations such as bytecode indices that are out of bounds for |
562 // some of the methods with the given name. | 617 // some of the methods with the given name. |
563 Future setBreakpoint({String methodName, int bytecodeIndex}) async { | 618 Future setBreakpoint({String methodName, int bytecodeIndex}) async { |
564 Iterable<DartinoFunction> functions = | 619 Iterable<DartinoFunction> functions = |
565 dartinoSystem.functionsWhere((f) => f.name == methodName); | 620 dartinoSystem.functionsWhere((f) => f.name == methodName); |
566 List<Breakpoint> breakpoints = []; | 621 List<Breakpoint> breakpoints = []; |
567 for (DartinoFunction function in functions) { | 622 for (DartinoFunction function in functions) { |
568 breakpoints.add( | 623 breakpoints.add( |
569 await setBreakpointHelper(methodName, function, bytecodeIndex)); | 624 await setBreakpointHelper(function, bytecodeIndex)); |
570 } | 625 } |
571 return breakpoints; | 626 return breakpoints; |
572 } | 627 } |
573 | 628 |
574 Future setFileBreakpointFromPosition(String name, | 629 Future<Breakpoint> setFileBreakpointFromPosition(String name, |
575 Uri file, | 630 Uri file, |
576 int position) async { | 631 int position) async { |
577 if (position == null) { | 632 if (position == null) { |
578 return null; | 633 return null; |
579 } | 634 } |
580 DebugInfo debugInfo = compiler.debugInfoForPosition( | 635 DebugInfo debugInfo = compiler.debugInfoForPosition( |
581 file, | 636 file, |
582 position, | 637 position, |
583 dartinoSystem); | 638 dartinoSystem); |
584 if (debugInfo == null) { | 639 if (debugInfo == null) { |
585 return null; | 640 return null; |
586 } | 641 } |
587 SourceLocation location = debugInfo.locationForPosition(position); | 642 SourceLocation location = debugInfo.locationForPosition(position); |
588 if (location == null) { | 643 if (location == null) { |
589 return null; | 644 return null; |
590 } | 645 } |
591 DartinoFunction function = debugInfo.function; | 646 DartinoFunction function = debugInfo.function; |
592 int bytecodeIndex = location.bytecodeIndex; | 647 int bytecodeIndex = location.bytecodeIndex; |
593 return setBreakpointHelper(function.name, function, bytecodeIndex); | 648 return setBreakpointHelper(function, bytecodeIndex); |
594 } | 649 } |
595 | 650 |
596 Future setFileBreakpointFromPattern(Uri file, | 651 Future<Breakpoint> setFileBreakpointFromPattern(Uri file, |
597 int line, | 652 int line, |
598 String pattern) async { | 653 String pattern) async { |
599 assert(line > 0); | 654 assert(line > 0); |
600 int position = compiler.positionInFileFromPattern(file, line - 1, pattern); | 655 int position = compiler.positionInFileFromPattern(file, line - 1, pattern); |
601 return setFileBreakpointFromPosition( | 656 return setFileBreakpointFromPosition( |
602 '$file:$line:$pattern', file, position); | 657 '$file:$line:$pattern', file, position); |
603 } | 658 } |
604 | 659 |
605 Future setFileBreakpoint(Uri file, int line, int column) async { | 660 Future<Breakpoint> setFileBreakpoint(Uri file, int line, int column) async { |
606 assert(line > 0 && column > 0); | 661 assert(line > 0 && column > 0); |
607 int position = compiler.positionInFile(file, line - 1, column - 1); | 662 int position = compiler.positionInFile(file, line - 1, column - 1); |
608 return setFileBreakpointFromPosition('$file:$line:$column', file, position); | 663 return setFileBreakpointFromPosition('$file:$line:$column', file, position); |
609 } | 664 } |
610 | 665 |
611 Future doDeleteOneShotBreakpoint(int processId, int breakpointId) async { | 666 Future<Null> doDeleteOneShotBreakpoint( |
| 667 int processId, int breakpointId) async { |
612 ProcessDeleteBreakpoint response = await runCommand( | 668 ProcessDeleteBreakpoint response = await runCommand( |
613 new ProcessDeleteOneShotBreakpoint(processId, breakpointId)); | 669 new ProcessDeleteOneShotBreakpoint(processId, breakpointId)); |
614 assert(response.id == breakpointId); | 670 assert(response.id == breakpointId); |
615 } | 671 } |
616 | 672 |
617 Future<Breakpoint> deleteBreakpoint(int id) async { | 673 Future<Breakpoint> deleteBreakpoint(int id) async { |
| 674 assert(!isRunning && !isTerminated); |
618 if (!debugState.breakpoints.containsKey(id)) { | 675 if (!debugState.breakpoints.containsKey(id)) { |
619 return null; | 676 return null; |
620 } | 677 } |
621 ProcessDeleteBreakpoint response = | 678 ProcessDeleteBreakpoint response = |
622 await runCommand(new ProcessDeleteBreakpoint(id)); | 679 await runCommand(new ProcessDeleteBreakpoint(id)); |
623 assert(response.id == id); | 680 assert(response.id == id); |
624 return debugState.breakpoints.remove(id); | 681 Breakpoint breakpoint = debugState.breakpoints.remove(id); |
| 682 listeners.forEach((DebugListener listener) { |
| 683 listener.breakpointRemoved(0, breakpoint); |
| 684 }); |
| 685 return breakpoint; |
625 } | 686 } |
626 | 687 |
627 List<Breakpoint> breakpoints() { | 688 List<Breakpoint> breakpoints() { |
628 assert(debugState.breakpoints != null); | 689 assert(debugState.breakpoints != null); |
629 return debugState.breakpoints.values.toList(); | 690 return debugState.breakpoints.values.toList(); |
630 } | 691 } |
631 | 692 |
632 Iterable<Uri> findSourceFiles(Pattern pattern) { | 693 Iterable<Uri> findSourceFiles(Pattern pattern) { |
633 return compiler.findSourceFiles(pattern); | 694 return compiler.findSourceFiles(pattern); |
634 } | 695 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 response.breakpointId == setBreakpoint.value; | 798 response.breakpointId == setBreakpoint.value; |
738 if (!success && !isTerminated && setBreakpoint.value != -1) { | 799 if (!success && !isTerminated && setBreakpoint.value != -1) { |
739 // Delete the initial one-time breakpoint as it wasn't hit. | 800 // Delete the initial one-time breakpoint as it wasn't hit. |
740 await doDeleteOneShotBreakpoint(processId, setBreakpoint.value); | 801 await doDeleteOneShotBreakpoint(processId, setBreakpoint.value); |
741 } | 802 } |
742 return response; | 803 return response; |
743 } | 804 } |
744 | 805 |
745 Future<VmCommand> cont() async { | 806 Future<VmCommand> cont() async { |
746 assert(isPaused); | 807 assert(isPaused); |
| 808 listeners.forEach((DebugListener listener) { |
| 809 listener.resume(0); |
| 810 }); |
747 return handleProcessStop(await runCommand(const ProcessContinue())); | 811 return handleProcessStop(await runCommand(const ProcessContinue())); |
748 } | 812 } |
749 | 813 |
750 bool selectFrame(int frame) { | 814 bool selectFrame(int frame) { |
751 if (debugState.currentBackTrace == null || | 815 if (debugState.currentBackTrace == null || |
752 debugState.currentBackTrace.actualFrameNumber(frame) == -1) { | 816 debugState.currentBackTrace.actualFrameNumber(frame) == -1) { |
753 return false; | 817 return false; |
754 } | 818 } |
755 debugState.currentFrame = frame; | 819 debugState.currentFrame = frame; |
756 return true; | 820 return true; |
(...skipping 29 matching lines...) Expand all Loading... |
786 } else { | 850 } else { |
787 assert(response is InstanceStructure); | 851 assert(response is InstanceStructure); |
788 List<DartValue> fields = await readInstanceStructureFields(response); | 852 List<DartValue> fields = await readInstanceStructureFields(response); |
789 debugState.currentUncaughtException = | 853 debugState.currentUncaughtException = |
790 new RemoteInstance(response, fields); | 854 new RemoteInstance(response, fields); |
791 } | 855 } |
792 } | 856 } |
793 return debugState.currentUncaughtException; | 857 return debugState.currentUncaughtException; |
794 } | 858 } |
795 | 859 |
796 Future<BackTrace> backTrace() async { | 860 Future<BackTrace> backTrace({int processId}) async { |
| 861 processId ??= debugState.currentProcess; |
797 assert(isSpawned); | 862 assert(isSpawned); |
798 if (debugState.currentBackTrace == null) { | 863 if (debugState.currentBackTrace == null) { |
799 ProcessBacktrace backtraceResponse = | 864 ProcessBacktrace backtraceResponse = |
800 await runCommand( | 865 await runCommand( |
801 new ProcessBacktraceRequest(debugState.currentProcess)); | 866 new ProcessBacktraceRequest(processId)); |
802 debugState.currentBackTrace = | 867 debugState.currentBackTrace = |
803 stackTraceFromBacktraceResponse(backtraceResponse); | 868 stackTraceFromBacktraceResponse(backtraceResponse); |
804 } | 869 } |
805 return debugState.currentBackTrace; | 870 return debugState.currentBackTrace; |
806 } | 871 } |
807 | 872 |
808 Future<BackTrace> backtraceForFiber(int fiber) async { | 873 Future<BackTrace> backtraceForFiber(int fiber) async { |
809 ProcessBacktrace backtraceResponse = | 874 ProcessBacktrace backtraceResponse = |
810 await runCommand(new ProcessFiberBacktraceRequest(fiber)); | 875 await runCommand(new ProcessFiberBacktraceRequest(fiber)); |
811 return stackTraceFromBacktraceResponse(backtraceResponse); | 876 return stackTraceFromBacktraceResponse(backtraceResponse); |
812 } | 877 } |
813 | 878 |
814 Future<List<BackTrace>> fibers() async { | 879 Future<List<BackTrace>> fibers() async { |
815 assert(isRunning || isPaused); | 880 assert(isRunning || isPaused); |
816 await runCommand(const NewMap(MapId.fibers)); | 881 await runCommand(const NewMap(MapId.fibers)); |
817 ProcessNumberOfStacks response = | 882 ProcessNumberOfStacks response = |
818 await runCommand(const ProcessAddFibersToMap()); | 883 await runCommand(const ProcessAddFibersToMap()); |
819 int numberOfFibers = response.value; | 884 int numberOfFibers = response.value; |
820 List<BackTrace> stacktraces = new List(numberOfFibers); | 885 List<BackTrace> stacktraces = new List(numberOfFibers); |
821 for (int i = 0; i < numberOfFibers; i++) { | 886 for (int i = 0; i < numberOfFibers; i++) { |
822 stacktraces[i] = await backtraceForFiber(i); | 887 stacktraces[i] = await backtraceForFiber(i); |
823 } | 888 } |
824 await runCommand(const DeleteMap(MapId.fibers)); | 889 await runCommand(const DeleteMap(MapId.fibers)); |
825 return stacktraces; | 890 return stacktraces; |
826 } | 891 } |
827 | 892 |
828 Future<List<int>> processes() async { | 893 Future<List<int>> processes() async { |
829 assert(isRunning || isPaused); | 894 assert(isSpawned); |
830 ProcessGetProcessIdsResult response = | 895 ProcessGetProcessIdsResult response = |
831 await runCommand(const ProcessGetProcessIds()); | 896 await runCommand(const ProcessGetProcessIds()); |
832 return response.ids; | 897 return response.ids; |
833 } | 898 } |
834 | 899 |
835 Future<BackTrace> processStack(int processId) async { | 900 Future<BackTrace> processStack(int processId) async { |
836 assert(isPaused); | 901 assert(isPaused); |
837 ProcessBacktrace backtraceResponse = | 902 ProcessBacktrace backtraceResponse = |
838 await runCommand(new ProcessBacktraceRequest(processId)); | 903 await runCommand(new ProcessBacktraceRequest(processId)); |
839 return stackTraceFromBacktraceResponse(backtraceResponse); | 904 return stackTraceFromBacktraceResponse(backtraceResponse); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 } | 1075 } |
1011 | 1076 |
1012 bool toggleInternal() { | 1077 bool toggleInternal() { |
1013 debugState.showInternalFrames = !debugState.showInternalFrames; | 1078 debugState.showInternalFrames = !debugState.showInternalFrames; |
1014 if (debugState.currentBackTrace != null) { | 1079 if (debugState.currentBackTrace != null) { |
1015 debugState.currentBackTrace.visibilityChanged(); | 1080 debugState.currentBackTrace.visibilityChanged(); |
1016 } | 1081 } |
1017 return debugState.showInternalFrames; | 1082 return debugState.showInternalFrames; |
1018 } | 1083 } |
1019 } | 1084 } |
OLD | NEW |