Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: runtime/observatory/lib/src/elements/debugger.dart

Issue 2523053002: Implement rewind: drop one or more frames from the debugger. (Closed)
Patch Set: code review Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/observatory/lib/src/service/object.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 return new Future.value(null); 202 return new Future.value(null);
203 } 203 }
204 if (debugger.currentFrame == null) { 204 if (debugger.currentFrame == null) {
205 debugger.console.print('No stack'); 205 debugger.console.print('No stack');
206 return new Future.value(null); 206 return new Future.value(null);
207 } 207 }
208 try { 208 try {
209 debugger.downFrame(count); 209 debugger.downFrame(count);
210 debugger.console.print('frame = ${debugger.currentFrame}'); 210 debugger.console.print('frame = ${debugger.currentFrame}');
211 } catch (e) { 211 } catch (e) {
212 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); 212 debugger.console.print(
213 'frame must be in range [${e.start}..${e.end-1}]');
213 } 214 }
214 return new Future.value(null); 215 return new Future.value(null);
215 } 216 }
216 217
217 String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; 218 String helpShort = 'Move down one or more frames (hotkey: [Page Down])';
218 219
219 String helpLong = 'Move down one or more frames.\n' 220 String helpLong = 'Move down one or more frames.\n'
220 '\n' 221 '\n'
221 'Hotkey: [Page Down]\n' 222 'Hotkey: [Page Down]\n'
222 '\n' 223 '\n'
(...skipping 13 matching lines...) Expand all
236 return new Future.value(null); 237 return new Future.value(null);
237 } 238 }
238 if (debugger.currentFrame == null) { 239 if (debugger.currentFrame == null) {
239 debugger.console.print('No stack'); 240 debugger.console.print('No stack');
240 return new Future.value(null); 241 return new Future.value(null);
241 } 242 }
242 try { 243 try {
243 debugger.upFrame(count); 244 debugger.upFrame(count);
244 debugger.console.print('frame = ${debugger.currentFrame}'); 245 debugger.console.print('frame = ${debugger.currentFrame}');
245 } on RangeError catch (e) { 246 } on RangeError catch (e) {
246 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); 247 debugger.console.print(
248 'frame must be in range [${e.start}..${e.end-1}]');
247 } 249 }
248 return new Future.value(null); 250 return new Future.value(null);
249 } 251 }
250 252
251 String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; 253 String helpShort = 'Move up one or more frames (hotkey: [Page Up])';
252 254
253 String helpLong = 'Move up one or more frames.\n' 255 String helpLong = 'Move up one or more frames.\n'
254 '\n' 256 '\n'
255 'Hotkey: [Page Up]\n' 257 'Hotkey: [Page Up]\n'
256 '\n' 258 '\n'
(...skipping 15 matching lines...) Expand all
272 return new Future.value(null); 274 return new Future.value(null);
273 } 275 }
274 if (debugger.currentFrame == null) { 276 if (debugger.currentFrame == null) {
275 debugger.console.print('No stack'); 277 debugger.console.print('No stack');
276 return new Future.value(null); 278 return new Future.value(null);
277 } 279 }
278 try { 280 try {
279 debugger.currentFrame = frame; 281 debugger.currentFrame = frame;
280 debugger.console.print('frame = ${debugger.currentFrame}'); 282 debugger.console.print('frame = ${debugger.currentFrame}');
281 } on RangeError catch (e) { 283 } on RangeError catch (e) {
282 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); 284 debugger.console.print(
285 'frame must be in range [${e.start}..${e.end-1}]');
283 } 286 }
284 return new Future.value(null); 287 return new Future.value(null);
285 } 288 }
286 289
287 String helpShort = 'Set the current frame'; 290 String helpShort = 'Set the current frame';
288 291
289 String helpLong = 'Set the current frame.\n' 292 String helpLong = 'Set the current frame.\n'
290 '\n' 293 '\n'
291 'Syntax: frame <number>\n' 294 'Syntax: frame <number>\n'
292 ' f <count>\n'; 295 ' f <count>\n';
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 399
397 String helpLong = 400 String helpLong =
398 'Continue running the isolate until it reaches the next source ' 401 'Continue running the isolate until it reaches the next source '
399 'location.\n' 402 'location.\n'
400 '\n' 403 '\n'
401 'Hotkey: [F10]\n' 404 'Hotkey: [F10]\n'
402 '\n' 405 '\n'
403 'Syntax: step\n'; 406 'Syntax: step\n';
404 } 407 }
405 408
409 class RewindCommand extends DebuggerCommand {
410 RewindCommand(Debugger debugger) : super(debugger, 'rewind', []);
411
412 Future run(List<String> args) async {
413 try {
414 int count = 1;
415 if (args.length == 1) {
416 count = int.parse(args[0]);
417 } else if (args.length > 1) {
418 debugger.console.print('rewind expects 0 or 1 argument');
419 return;
420 } else if (count < 1 || count > debugger.stackDepth) {
421 debugger.console.print(
422 'frame must be in range [1..${debugger.stackDepth - 1}]');
423 return;
424 }
425 await debugger.rewind(count);
426 } on S.ServerRpcException catch(e) {
427 if (e.code == S.ServerRpcException.kCannotResume) {
428 debugger.console.printRed(e.data['details']);
429 } else {
430 rethrow;
431 }
432 }
433 }
434
435 String helpShort = 'Rewind the stack to a previous frame';
436
437 String helpLong =
438 'Rewind the stack to a previous frame.\n'
439 '\n'
440 'Syntax: rewind\n'
441 ' rewind <count>\n';
442 }
443
444 class ReloadCommand extends DebuggerCommand {
445 ReloadCommand(Debugger debugger) : super(debugger, 'reload', []);
446
447 Future run(List<String> args) async {
448 try {
449 int count = 1;
450 if (args.length > 0) {
451 debugger.console.print('reload expects no arguments');
452 return;
453 }
454 await debugger.isolate.reloadSources();
455 debugger.console.print('reload complete');
456 await debugger.refreshStack();
457 } on S.ServerRpcException catch(e) {
458 if (e.code == S.ServerRpcException.kIsolateReloadBarred ||
459 e.code == S.ServerRpcException.kIsolateReloadFailed ||
460 e.code == S.ServerRpcException.kIsolateIsReloading) {
461 debugger.console.printRed(e.data['details']);
462 } else {
463 rethrow;
464 }
465 }
466 }
467
468 String helpShort = 'Reload the sources for the current isolate';
469
470 String helpLong =
471 'Reload the sources for the current isolate.\n'
472 '\n'
473 'Syntax: reload\n';
474 }
475
406 class ClsCommand extends DebuggerCommand { 476 class ClsCommand extends DebuggerCommand {
407 ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} 477 ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {}
408 478
409 Future run(List<String> args) { 479 Future run(List<String> args) {
410 debugger.console.clear(); 480 debugger.console.clear();
411 debugger.console.newline(); 481 debugger.console.newline();
412 return new Future.value(null); 482 return new Future.value(null);
413 } 483 }
414 484
415 String helpShort = 'Clear the console'; 485 String helpShort = 'Clear the console';
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 debugger.console.print('Unable to set breakpoint at ${loc}'); 726 debugger.console.print('Unable to set breakpoint at ${loc}');
657 } else { 727 } else {
658 rethrow; 728 rethrow;
659 } 729 }
660 } 730 }
661 } else { 731 } else {
662 assert(loc.script != null); 732 assert(loc.script != null);
663 var script = loc.script; 733 var script = loc.script;
664 await script.load(); 734 await script.load();
665 if (loc.line < 1 || loc.line > script.lines.length) { 735 if (loc.line < 1 || loc.line > script.lines.length) {
666 debugger.console 736 debugger.console.print(
667 .print('line number must be in range [1,${script.lines.length}]'); 737 'line number must be in range [1..${script.lines.length}]');
668 return; 738 return;
669 } 739 }
670 try { 740 try {
671 await debugger.isolate.addBreakpoint(script, loc.line, loc.col); 741 await debugger.isolate.addBreakpoint(script, loc.line, loc.col);
672 } on S.ServerRpcException catch (e) { 742 } on S.ServerRpcException catch (e) {
673 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { 743 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) {
674 debugger.console.print('Unable to set breakpoint at ${loc}'); 744 debugger.console.print('Unable to set breakpoint at ${loc}');
675 } else { 745 } else {
676 rethrow; 746 rethrow;
677 } 747 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 807 }
738 if (loc.function != null) { 808 if (loc.function != null) {
739 debugger.console.print('Ignoring breakpoint at $loc: ' 809 debugger.console.print('Ignoring breakpoint at $loc: '
740 'Clearing function breakpoints not yet implemented'); 810 'Clearing function breakpoints not yet implemented');
741 return; 811 return;
742 } 812 }
743 813
744 var script = loc.script; 814 var script = loc.script;
745 if (loc.line < 1 || loc.line > script.lines.length) { 815 if (loc.line < 1 || loc.line > script.lines.length) {
746 debugger.console 816 debugger.console
747 .print('line number must be in range [1,${script.lines.length}]'); 817 .print('line number must be in range [1..${script.lines.length}]');
748 return; 818 return;
749 } 819 }
750 var lineInfo = script.getLine(loc.line); 820 var lineInfo = script.getLine(loc.line);
751 var bpts = lineInfo.breakpoints; 821 var bpts = lineInfo.breakpoints;
752 var foundBreakpoint = false; 822 var foundBreakpoint = false;
753 if (bpts != null) { 823 if (bpts != null) {
754 var bptList = bpts.toList(); 824 var bptList = bpts.toList();
755 for (var bpt in bptList) { 825 for (var bpt in bptList) {
756 if (loc.col == null || 826 if (loc.col == null ||
757 loc.col == script.tokenToCol(bpt.location.tokenPos)) { 827 loc.col == script.tokenToCol(bpt.location.tokenPos)) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 String helpLong = 'Show current frame.\n' 962 String helpLong = 'Show current frame.\n'
893 '\n' 963 '\n'
894 'Syntax: info frame\n'; 964 'Syntax: info frame\n';
895 } 965 }
896 966
897 class IsolateCommand extends DebuggerCommand { 967 class IsolateCommand extends DebuggerCommand {
898 IsolateCommand(Debugger debugger) 968 IsolateCommand(Debugger debugger)
899 : super(debugger, 'isolate', [ 969 : super(debugger, 'isolate', [
900 new IsolateListCommand(debugger), 970 new IsolateListCommand(debugger),
901 new IsolateNameCommand(debugger), 971 new IsolateNameCommand(debugger),
902 new IsolateReloadCommand(debugger),
903 ]) { 972 ]) {
904 alias = 'i'; 973 alias = 'i';
905 } 974 }
906 975
907 Future run(List<String> args) { 976 Future run(List<String> args) {
908 if (args.length != 1) { 977 if (args.length != 1) {
909 debugger.console.print('isolate expects one argument'); 978 debugger.console.print('isolate expects one argument');
910 return new Future.value(null); 979 return new Future.value(null);
911 } 980 }
912 var arg = args[0].trim(); 981 var arg = args[0].trim();
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 return debugger.isolate.setName(args[0]); 1104 return debugger.isolate.setName(args[0]);
1036 } 1105 }
1037 1106
1038 String helpShort = 'Rename the current isolate'; 1107 String helpShort = 'Rename the current isolate';
1039 1108
1040 String helpLong = 'Rename the current isolate.\n' 1109 String helpLong = 'Rename the current isolate.\n'
1041 '\n' 1110 '\n'
1042 'Syntax: isolate name <name>\n'; 1111 'Syntax: isolate name <name>\n';
1043 } 1112 }
1044 1113
1045 class IsolateReloadCommand extends DebuggerCommand {
1046 IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []);
1047
1048 Future run(List<String> args) async {
1049 if (debugger.isolate == null) {
1050 debugger.console.print('There is no current vm');
1051 return;
1052 }
1053
1054 await debugger.isolate.reloadSources();
1055
1056 debugger.console.print('Isolate reloading....');
1057 }
1058
1059 String helpShort = 'Reload the sources for the current isolate.';
1060
1061 String helpLong = 'Reload the sources for the current isolate.\n'
1062 '\n'
1063 'Syntax: reload\n';
1064 }
1065
1066 class InfoCommand extends DebuggerCommand { 1114 class InfoCommand extends DebuggerCommand {
1067 InfoCommand(Debugger debugger) 1115 InfoCommand(Debugger debugger)
1068 : super(debugger, 'info', [ 1116 : super(debugger, 'info', [
1069 new InfoBreakpointsCommand(debugger), 1117 new InfoBreakpointsCommand(debugger),
1070 new InfoFrameCommand(debugger) 1118 new InfoFrameCommand(debugger)
1071 ]); 1119 ]);
1072 1120
1073 Future run(List<String> args) { 1121 Future run(List<String> args) {
1074 debugger.console.print("'info' expects a subcommand (see 'help info')"); 1122 debugger.console.print("'info' expects a subcommand (see 'help info')");
1075 return new Future.value(null); 1123 return new Future.value(null);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 new DeleteCommand(this), 1412 new DeleteCommand(this),
1365 new DownCommand(this), 1413 new DownCommand(this),
1366 new FinishCommand(this), 1414 new FinishCommand(this),
1367 new FrameCommand(this), 1415 new FrameCommand(this),
1368 new HelpCommand(this), 1416 new HelpCommand(this),
1369 new InfoCommand(this), 1417 new InfoCommand(this),
1370 new IsolateCommand(this), 1418 new IsolateCommand(this),
1371 new LogCommand(this), 1419 new LogCommand(this),
1372 new PauseCommand(this), 1420 new PauseCommand(this),
1373 new PrintCommand(this), 1421 new PrintCommand(this),
1422 new ReloadCommand(this),
1374 new RefreshCommand(this), 1423 new RefreshCommand(this),
1424 new RewindCommand(this),
1375 new SetCommand(this), 1425 new SetCommand(this),
1376 new SmartNextCommand(this), 1426 new SmartNextCommand(this),
1377 new StepCommand(this), 1427 new StepCommand(this),
1378 new SyncNextCommand(this), 1428 new SyncNextCommand(this),
1379 new UpCommand(this), 1429 new UpCommand(this),
1380 new VmCommand(this), 1430 new VmCommand(this),
1381 ], _history); 1431 ], _history);
1382 _consolePrinter = new _ConsoleStreamPrinter(this); 1432 _consolePrinter = new _ConsoleStreamPrinter(this);
1383 } 1433 }
1384 1434
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 if (event is M.PauseExitEvent) { 1922 if (event is M.PauseExitEvent) {
1873 console.print("Type 'continue' [F7] to exit the isolate"); 1923 console.print("Type 'continue' [F7] to exit the isolate");
1874 return new Future.value(null); 1924 return new Future.value(null);
1875 } 1925 }
1876 return isolate.stepInto(); 1926 return isolate.stepInto();
1877 } else { 1927 } else {
1878 console.print('The program is already running'); 1928 console.print('The program is already running');
1879 return new Future.value(null); 1929 return new Future.value(null);
1880 } 1930 }
1881 } 1931 }
1932
1933 Future rewind(int count) {
1934 if (isolatePaused()) {
1935 var event = isolate.pauseEvent;
1936 if (event is M.PauseExitEvent) {
1937 console.print("Type 'continue' [F7] to exit the isolate");
1938 return new Future.value(null);
1939 }
1940 return isolate.rewind(count);
1941 } else {
1942 console.print('The program must be paused');
1943 return new Future.value(null);
1944 }
1945 }
1882 } 1946 }
1883 1947
1884 class DebuggerPageElement extends HtmlElement implements Renderable { 1948 class DebuggerPageElement extends HtmlElement implements Renderable {
1885 static const tag = 1949 static const tag =
1886 const Tag<DebuggerPageElement>('debugger-page', dependencies: const [ 1950 const Tag<DebuggerPageElement>('debugger-page', dependencies: const [
1887 NavTopMenuElement.tag, 1951 NavTopMenuElement.tag,
1888 NavVMMenuElement.tag, 1952 NavVMMenuElement.tag,
1889 NavIsolateMenuElement.tag, 1953 NavIsolateMenuElement.tag,
1890 NavNotifyElement.tag, 1954 NavNotifyElement.tag,
1891 ]); 1955 ]);
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 ..classes = ['frameSummary'] 2570 ..classes = ['frameSummary']
2507 ..children = content 2571 ..children = content
2508 ]; 2572 ];
2509 } 2573 }
2510 2574
2511 String makeExpandKey(String key) { 2575 String makeExpandKey(String key) {
2512 return '${_frame.function.qualifiedName}/${key}'; 2576 return '${_frame.function.qualifiedName}/${key}';
2513 } 2577 }
2514 2578
2515 bool matchFrame(S.Frame newFrame) { 2579 bool matchFrame(S.Frame newFrame) {
2516 return newFrame.function.id == _frame.function.id; 2580 return (newFrame.function.id == _frame.function.id &&
2581 newFrame.location.script.id ==
2582 frame.location.script.id);
2517 } 2583 }
2518 2584
2519 void updateFrame(S.Frame newFrame) { 2585 void updateFrame(S.Frame newFrame) {
2520 assert(matchFrame(newFrame)); 2586 assert(matchFrame(newFrame));
2521 _frame = newFrame; 2587 _frame = newFrame;
2522 } 2588 }
2523 2589
2524 S.Script get script => _frame.location.script; 2590 S.Script get script => _frame.location.script;
2525 2591
2526 int _varsTop(varsDiv) { 2592 int _varsTop(varsDiv) {
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
3190 ..setAttribute('height', '24') 3256 ..setAttribute('height', '24')
3191 ..children = [ 3257 ..children = [
3192 new PathElement() 3258 new PathElement()
3193 ..setAttribute( 3259 ..setAttribute(
3194 'd', 3260 'd',
3195 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' 3261 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 '
3196 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' 3262 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 '
3197 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' 3263 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 '
3198 '9h2V7h-2v2z') 3264 '9h2V7h-2v2z')
3199 ]; 3265 ];
OLDNEW
« no previous file with comments | « no previous file | runtime/observatory/lib/src/service/object.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698