Chromium Code Reviews| Index: runtime/observatory/lib/src/elements/debugger.dart |
| diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart |
| index 8b91efffe5b35548afe24bb75b7924feafcf80b1..3cf1be997a4ba9a1196c407cd924b54bc677d22b 100644 |
| --- a/runtime/observatory/lib/src/elements/debugger.dart |
| +++ b/runtime/observatory/lib/src/elements/debugger.dart |
| @@ -209,7 +209,8 @@ class DownCommand extends DebuggerCommand { |
| debugger.downFrame(count); |
| debugger.console.print('frame = ${debugger.currentFrame}'); |
| } catch (e) { |
| - debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| + debugger.console.print( |
| + 'frame must be in range [${e.start}..${e.end-1}]'); |
| } |
| return new Future.value(null); |
| } |
| @@ -243,7 +244,8 @@ class UpCommand extends DebuggerCommand { |
| debugger.upFrame(count); |
| debugger.console.print('frame = ${debugger.currentFrame}'); |
| } on RangeError catch (e) { |
| - debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| + debugger.console.print( |
| + 'frame must be in range [${e.start}..${e.end-1}]'); |
| } |
| return new Future.value(null); |
| } |
| @@ -279,7 +281,8 @@ class FrameCommand extends DebuggerCommand { |
| debugger.currentFrame = frame; |
| debugger.console.print('frame = ${debugger.currentFrame}'); |
| } on RangeError catch (e) { |
| - debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| + debugger.console.print( |
| + 'frame must be in range [${e.start}..${e.end-1}]'); |
| } |
| return new Future.value(null); |
| } |
| @@ -403,6 +406,74 @@ class StepCommand extends DebuggerCommand { |
| 'Syntax: step\n'; |
| } |
| +class RewindCommand extends DebuggerCommand { |
| + RewindCommand(Debugger debugger) : super(debugger, 'rewind', []); |
| + |
| + Future run(List<String> args) async { |
| + try { |
| + int count = 1; |
| + if (args.length == 1) { |
| + count = int.parse(args[0]); |
| + } else if (args.length > 1) { |
| + debugger.console.print('rewind expects 0 or 1 argument'); |
| + return; |
| + } else if (count < 1 || count > debugger.stackDepth) { |
| + debugger.console.print( |
| + 'frame must be in range [1..${debugger.stackDepth - 1}]'); |
| + return; |
| + } |
| + await debugger.rewind(count); |
| + } on S.ServerRpcException catch(e) { |
| + if (e.code == S.ServerRpcException.kCannotResume) { |
| + debugger.console.printRed(e.data['details']); |
| + } else { |
| + rethrow; |
| + } |
| + } |
| + } |
| + |
| + String helpShort = 'Rewind the stack to a previous frame'; |
| + |
| + String helpLong = |
| + 'Rewind the stack to a previous frame.\n' |
| + '\n' |
| + 'Syntax: rewind\n' |
| + ' rewind <count>\n'; |
| +} |
| + |
| +class ReloadCommand extends DebuggerCommand { |
| + ReloadCommand(Debugger debugger) : super(debugger, 'reload', []); |
| + |
| + Future run(List<String> args) async { |
| + try { |
| + int count = 1; |
| + if (args.length > 0) { |
| + debugger.console.print('reload expects no arguments'); |
| + return; |
| + } |
| + await debugger.isolate.reloadSources(); |
| + // debugger.clearStack(); |
| + debugger.console.print('reload complete'); |
| + await debugger.refreshStack(); |
| + } on S.ServerRpcException catch(e) { |
| + if (e.code == S.ServerRpcException.kIsolateReloadBarred || |
| + e.code == S.ServerRpcException.kIsolateReloadFailed || |
| + e.code == S.ServerRpcException.kIsolateIsReloading) { |
| + debugger.console.printRed(e.data['details']); |
| + } else { |
| + rethrow; |
| + } |
| + } |
| + } |
| + |
| + String helpShort = 'Reload the sources for the current isolate'; |
| + |
| + String helpLong = |
| + 'Reload the sources for the current isolate.\n' |
| + '\n' |
| + 'Syntax: reload\n'; |
| +} |
| + |
| class ClsCommand extends DebuggerCommand { |
| ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} |
| @@ -663,8 +734,8 @@ class BreakCommand extends DebuggerCommand { |
| var script = loc.script; |
| await script.load(); |
| if (loc.line < 1 || loc.line > script.lines.length) { |
| - debugger.console |
| - .print('line number must be in range [1,${script.lines.length}]'); |
| + debugger.console.print( |
| + 'line number must be in range [1..${script.lines.length}]'); |
| return; |
| } |
| try { |
| @@ -744,7 +815,7 @@ class ClearCommand extends DebuggerCommand { |
| var script = loc.script; |
| if (loc.line < 1 || loc.line > script.lines.length) { |
| debugger.console |
| - .print('line number must be in range [1,${script.lines.length}]'); |
| + .print('line number must be in range [1..${script.lines.length}]'); |
| return; |
| } |
| var lineInfo = script.getLine(loc.line); |
| @@ -899,7 +970,6 @@ class IsolateCommand extends DebuggerCommand { |
| : super(debugger, 'isolate', [ |
| new IsolateListCommand(debugger), |
| new IsolateNameCommand(debugger), |
| - new IsolateReloadCommand(debugger), |
| ]) { |
| alias = 'i'; |
| } |
| @@ -1042,27 +1112,6 @@ class IsolateNameCommand extends DebuggerCommand { |
| 'Syntax: isolate name <name>\n'; |
| } |
| -class IsolateReloadCommand extends DebuggerCommand { |
| - IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []); |
| - |
| - Future run(List<String> args) async { |
| - if (debugger.isolate == null) { |
| - debugger.console.print('There is no current vm'); |
| - return; |
| - } |
| - |
| - await debugger.isolate.reloadSources(); |
| - |
| - debugger.console.print('Isolate reloading....'); |
| - } |
| - |
| - String helpShort = 'Reload the sources for the current isolate.'; |
| - |
| - String helpLong = 'Reload the sources for the current isolate.\n' |
| - '\n' |
| - 'Syntax: reload\n'; |
| -} |
| - |
| class InfoCommand extends DebuggerCommand { |
| InfoCommand(Debugger debugger) |
| : super(debugger, 'info', [ |
| @@ -1371,7 +1420,9 @@ class ObservatoryDebugger extends Debugger { |
| new LogCommand(this), |
| new PauseCommand(this), |
| new PrintCommand(this), |
| + new ReloadCommand(this), |
| new RefreshCommand(this), |
| + new RewindCommand(this), |
| new SetCommand(this), |
| new SmartNextCommand(this), |
| new StepCommand(this), |
| @@ -1456,6 +1507,10 @@ class ObservatoryDebugger extends Debugger { |
| }); |
| } |
| + void clearStack() { |
| + stackElement.clearStack(); |
| + } |
| + |
| Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) { |
| return isolate.getStack().then((result) { |
| if (result.isSentinel) { |
| @@ -1879,6 +1934,20 @@ class ObservatoryDebugger extends Debugger { |
| return new Future.value(null); |
| } |
| } |
| + |
| + Future rewind(int count) { |
| + if (isolatePaused()) { |
| + var event = isolate.pauseEvent; |
| + if (event is M.PauseExitEvent) { |
| + console.print("Type 'continue' [F7] to exit the isolate"); |
| + return new Future.value(null); |
| + } |
| + return isolate.rewind(count); |
| + } else { |
| + console.print('The program must be paused'); |
| + return new Future.value(null); |
| + } |
| + } |
| } |
| class DebuggerPageElement extends HtmlElement implements Renderable { |
| @@ -2273,6 +2342,17 @@ class DebuggerStackElement extends HtmlElement implements Renderable { |
| isSampled = pauseEvent == null; |
| } |
| + void clearStack() { |
| + List frameElements = _frameList.children; |
|
Cutch
2016/11/22 22:27:50
can we not just call clear on the lists?
turnidge
2016/11/22 22:54:06
Turns out this code was dead. Removed.
|
| + for (int i = 0; i < frameElements.length; i++) { |
| + frameElements.removeAt(0); |
| + } |
| + List messageElements = _messageList.children; |
| + for (int i = 0; i < messageElements.length; i++) { |
| + messageElements.removeAt(0); |
| + } |
| + } |
| + |
| void setCurrentFrame(int value) { |
| currentFrame = value; |
| List frameElements = _frameList.children; |
| @@ -2513,7 +2593,9 @@ class DebuggerFrameElement extends HtmlElement implements Renderable { |
| } |
| bool matchFrame(S.Frame newFrame) { |
| - return newFrame.function.id == _frame.function.id; |
| + return (newFrame.function.id == _frame.function.id && |
| + newFrame.location.script.id == |
| + frame.location.script.id); |
| } |
| void updateFrame(S.Frame newFrame) { |