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

Side by Side Diff: tools/ddbg_service/lib/debugger.dart

Issue 562273005: ddbg_service changes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « tools/ddbg_service/lib/commando.dart ('k') | no next file » | 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; 5 library debugger;
6 6
7 import "dart:async"; 7 import "dart:async";
8 import "dart:io"; 8 import "dart:io";
9 9
10 import "package:ddbg/commando.dart"; 10 import "package:ddbg/commando.dart";
11 import "package:observatory/service_io.dart"; 11 import "package:observatory/service_io.dart";
12 12
13 class Debugger { 13 class Debugger {
14 Commando cmdo; 14 Commando cmdo;
15 var _cmdoSubscription; 15 var _cmdoSubscription;
16 16
17 CommandList _commands;
18
17 VM _vm; 19 VM _vm;
18 VM get vm => _vm; 20 VM get vm => _vm;
19 set vm(VM vm) { 21 set vm(VM vm) {
20 if (_vm == vm) { 22 if (_vm == vm) {
21 // Do nothing. 23 // Do nothing.
22 return; 24 return;
23 } 25 }
24 if (_vm != null) { 26 if (_vm != null) {
25 _vm.disconnect(); 27 _vm.disconnect();
26 } 28 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 error is ServiceError) { 86 error is ServiceError) {
85 // These are handled elsewhere. Ignore. 87 // These are handled elsewhere. Ignore.
86 return; 88 return;
87 } 89 }
88 cmdo.print('\n--------\nExiting due to unexpected error:\n' 90 cmdo.print('\n--------\nExiting due to unexpected error:\n'
89 ' $error\n$trace\n'); 91 ' $error\n$trace\n');
90 quit(); 92 quit();
91 } 93 }
92 94
93 Debugger() { 95 Debugger() {
94 cmdo = new Commando(completer: completeCommand); 96 cmdo = new Commando(completer: _completeCommand);
95 _cmdoSubscription = cmdo.commands.listen(_processCommand, 97 _cmdoSubscription = cmdo.commands.listen(_processCommand,
96 onError: _cmdoError, 98 onError: _cmdoError,
97 onDone: _cmdoDone); 99 onDone: _cmdoDone);
100 _commands = new CommandList();
101 _commands.register(new AttachCommand());
102 _commands.register(new DetachCommand());
103 _commands.register(new HelpCommand(_commands));
104 _commands.register(new IsolateCommand());
105 _commands.register(new QuitCommand());
98 } 106 }
99 107
100 Future _closeCmdo() { 108 Future _closeCmdo() {
101 var sub = _cmdoSubscription; 109 var sub = _cmdoSubscription;
102 _cmdoSubscription = null; 110 _cmdoSubscription = null;
103 cmdo = null; 111 cmdo = null;
104 112
105 var future = sub.cancel(); 113 var future = sub.cancel();
106 if (future != null) { 114 if (future != null) {
107 return future; 115 return future;
108 } else { 116 } else {
109 return new Future.value(); 117 return new Future.value();
110 } 118 }
111 } 119 }
112 120
113 Future quit() { 121 Future quit() {
114 return Future.wait([_closeCmdo()]).then((_) { 122 return Future.wait([_closeCmdo()]).then((_) {
115 exit(0); 123 exit(0);
116 }); 124 });
117 } 125 }
118 126
119 void _cmdoError(self, parent, zone, error, StackTrace trace) { 127 void _cmdoError(error, StackTrace trace) {
120 cmdo.print('\n--------\nExiting due to unexpected error:\n' 128 cmdo.print('\n--------\nExiting due to unexpected error:\n'
121 ' $error\n$trace\n'); 129 ' $error\n$trace\n');
122 quit(); 130 quit();
123 } 131 }
124 132
125 void _cmdoDone() { 133 void _cmdoDone() {
126 quit(); 134 quit();
127 } 135 }
128 136
137 List<String> _completeCommand(List<String> commandParts) {
138 return _commands.complete(commandParts);
139 }
140
129 void _processCommand(String cmdLine) { 141 void _processCommand(String cmdLine) {
130 void huh() { 142 void huh() {
131 cmdo.print("'$cmdLine' not understood, try 'help' for help."); 143 cmdo.print("'$cmdLine' not understood, try 'help' for help.");
132 } 144 }
133 145
134 cmdo.hide(); 146 cmdo.hide();
135 cmdLine = cmdLine.trim(); 147 cmdLine = cmdLine.trim();
136 var args = cmdLine.split(' '); 148 var args = cmdLine.split(' ');
137 if (args.length == 0) { 149 if (args.length == 0) {
138 return; 150 return;
139 } 151 }
140 var command = args[0]; 152 var command = args[0];
141 var matches = matchCommand(command, true); 153 var matches = _commands.match(command, true);
142 if (matches.length == 0) { 154 if (matches.length == 0) {
143 huh(); 155 huh();
144 cmdo.show(); 156 cmdo.show();
145 } else if (matches.length == 1) { 157 } else if (matches.length == 1) {
146 matches[0].run(this, args).then((_) { 158 matches[0].run(this, args).then((_) {
147 cmdo.show(); 159 cmdo.show();
148 }); 160 });
149 } else { 161 } else {
150 var matchNames = matches.map((handler) => handler.name); 162 var matchNames = matches.map((handler) => handler.name);
151 cmdo.print("Ambigous command '$command' : ${matchNames.toList()}"); 163 cmdo.print("Ambigous command '$command' : ${matchNames.toList()}");
152 cmdo.show(); 164 cmdo.show();
153 } 165 }
154 } 166 }
155 167
156 } 168 }
157 169
158 // Every debugger command extends this base class. 170 // Every debugger command extends this base class.
159 abstract class Command { 171 abstract class Command {
160 String get name; 172 String get name;
161 String get helpShort; 173 String get helpShort;
162 void printHelp(Debugger debugger, List<String> args); 174 void printHelp(Debugger debugger, List<String> args);
163 Future run(Debugger debugger, List<String> args); 175 Future run(Debugger debugger, List<String> args);
176 List<String> complete(List<String> commandParts) {
177 return ["$name ${commandParts.join(' ')}"];
178
179 }
164 } 180 }
165 181
166 class AttachCommand extends Command { 182 class AttachCommand extends Command {
167 final name = 'attach'; 183 final name = 'attach';
168 final helpShort = 'Attach to a running Dart VM'; 184 final helpShort = 'Attach to a running Dart VM';
169 void printHelp(Debugger debugger, List<String> args) { 185 void printHelp(Debugger debugger, List<String> args) {
170 debugger.cmdo.print(''' 186 debugger.cmdo.print('''
171 ----- attach ----- 187 ----- attach -----
172 188
173 Attach to the Dart VM running at the indicated host:port. If no 189 Attach to the Dart VM running at the indicated host:port. If no
(...skipping 22 matching lines...) Expand all
196 for (var isolate in vm.isolates) { 212 for (var isolate in vm.isolates) {
197 if (isolate.name == 'root') { 213 if (isolate.name == 'root') {
198 debugger.isolate = isolate; 214 debugger.isolate = isolate;
199 } 215 }
200 } 216 }
201 } 217 }
202 }); 218 });
203 } 219 }
204 } 220 }
205 221
222 class CommandList {
223 List _commands = new List<Command>();
224
225 void register(Command cmd) {
226 _commands.add(cmd);
227 }
228
229 List<Command> match(String commandName, bool exactMatchWins) {
230 var matches = [];
231 for (var command in _commands) {
232 if (command.name.startsWith(commandName)) {
233 if (exactMatchWins && command.name == commandName) {
234 // Exact match
235 return [command];
236 } else {
237 matches.add(command);
238 }
239 }
240 }
241 return matches;
242 }
243
244 List<String> complete(List<String> commandParts) {
245 var completions = new List<String>();
246 String prefix = commandParts[0];
247 for (var command in _commands) {
248 if (command.name.startsWith(prefix)) {
249 completions.addAll(command.complete(commandParts.sublist(1)));
250 }
251 }
252 return completions;
253 }
254
255 void printHelp(Debugger debugger, List<String> args) {
256 var cmdo = debugger.cmdo;
257 if (args.length <= 1) {
258 cmdo.print("\nDebugger commands:\n");
259 for (var command in _commands) {
260 cmdo.print(' ${command.name.padRight(11)} ${command.helpShort}');
261 }
262 cmdo.print("For more information about a particular command, type:\n\n"
263 " help <command>\n");
264
265 cmdo.print("Commands may be abbreviated: e.g. type 'h' for 'help.\n");
266 } else {
267 var commandName = args[1];
268 var matches =match(commandName, true);
269 if (matches.length == 0) {
270 cmdo.print("Command '$commandName' not recognized. "
271 "Try 'help' for a list of commands.");
272 } else {
273 for (var command in matches) {
274 command.printHelp(debugger, args);
275 }
276 }
277 }
278 }
279 }
280
206 class DetachCommand extends Command { 281 class DetachCommand extends Command {
207 final name = 'detach'; 282 final name = 'detach';
208 final helpShort = 'Detach from a running Dart VM'; 283 final helpShort = 'Detach from a running Dart VM';
209 void printHelp(Debugger debugger, List<String> args) { 284 void printHelp(Debugger debugger, List<String> args) {
210 cmdo.print(''' 285 debugger.cmdo.print('''
211 ----- detach ----- 286 ----- detach -----
212 287
213 Detach from the Dart VM. 288 Detach from the Dart VM.
214 289
215 Usage: 290 Usage:
216 detach 291 detach
217 '''); 292 ''');
218 } 293 }
219 294
220 Future run(Debugger debugger, List<String> args) { 295 Future run(Debugger debugger, List<String> args) {
221 var cmdo = debugger.cmdo; 296 var cmdo = debugger.cmdo;
222 if (args.length > 1) { 297 if (args.length > 1) {
223 cmdo.print('$name expects no arguments'); 298 cmdo.print('$name expects no arguments');
224 return new Future.value(); 299 return new Future.value();
225 } 300 }
226 if (debugger.vm == null) { 301 if (debugger.vm == null) {
227 cmdo.print('No VM is attached'); 302 cmdo.print('No VM is attached');
228 } else { 303 } else {
229 debugger.vm = null; 304 debugger.vm = null;
230 } 305 }
231 return new Future.value(); 306 return new Future.value();
232 } 307 }
233 } 308 }
234 309
235 class HelpCommand extends Command { 310 class HelpCommand extends Command {
311 HelpCommand(this._commands);
312 final CommandList _commands;
313
236 final name = 'help'; 314 final name = 'help';
237 final helpShort = 'Show a list of debugger commands'; 315 final helpShort = 'Show a list of debugger commands';
238 void printHelp(Debugger debugger, List<String> args) { 316 void printHelp(Debugger debugger, List<String> args) {
239 debugger.cmdo.print(''' 317 debugger.cmdo.print('''
240 ----- help ----- 318 ----- help -----
241 319
242 Show a list of debugger commands or get more information about a 320 Show a list of debugger commands or get more information about a
243 particular command. 321 particular command.
244 322
245 Usage: 323 Usage:
246 help 324 help
247 help <command> 325 help <command>
248 '''); 326 ''');
249 } 327 }
250 328
251 Future run(Debugger debugger, List<String> args) { 329 Future run(Debugger debugger, List<String> args) {
252 var cmdo = debugger.cmdo; 330 _commands.printHelp(debugger, args);
253 if (args.length <= 1) { 331 return new Future.value();
254 cmdo.print("\nDebugger commands:\n"); 332 }
255 for (var command in commandList) {
256 cmdo.print(' ${command.name.padRight(11)} ${command.helpShort}');
257 }
258 cmdo.print("For more information about a particular command, type:\n\n"
259 " help <command>\n");
260 333
261 cmdo.print("Commands may be abbreviated: e.g. type 'h' for 'help.\n"); 334 List<String> complete(List<String> commandParts) {
262 } else { 335 if (commandParts.isEmpty) {
263 var commandName = args[1]; 336 return ['$name '];
264 var matches = matchCommand(commandName, true);
265 if (matches.length == 0) {
266 cmdo.print("Command '$commandName' not recognized. "
267 "Try 'help' for a list of commands.");
268 } else {
269 for (var command in matches) {
270 command.printHelp(debugger, args);
271 }
272 }
273 } 337 }
274 338 return _commands.complete(commandParts).map((value) {
275 return new Future.value(); 339 return '$name $value';
340 });
276 } 341 }
277 } 342 }
278 343
279 class IsolateCommand extends Command { 344 class IsolateCommand extends Command {
280 final name = 'isolate'; 345 final name = 'isolate';
281 final helpShort = 'Isolate control'; 346 final helpShort = 'Isolate control';
282 void printHelp(Debugger debugger, List<String> args) { 347 void printHelp(Debugger debugger, List<String> args) {
283 debugger.cmdo.print(''' 348 debugger.cmdo.print('''
284 ----- isolate ----- 349 ----- isolate -----
285 350
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 } else if (isolate.loading) { 433 } else if (isolate.loading) {
369 // TODO(turnidge): This is weird in a command line debugger. 434 // TODO(turnidge): This is weird in a command line debugger.
370 sb.write('(not available)'); 435 sb.write('(not available)');
371 } 436 }
372 sb.write('\n'); 437 sb.write('\n');
373 } 438 }
374 cmdo.print(sb); 439 cmdo.print(sb);
375 }); 440 });
376 return new Future.value(); 441 return new Future.value();
377 } 442 }
443
444 List<String> complete(List<String> commandParts) {
445 if (commandParts.isEmpty) {
446 return ['$name ${commandParts.join(" ")}'];
447 } else {
448 var completions = _commands.complete(commandParts);
449 return completions.map((completion) {
450 return '$name $completion';
451 });
452 }
453 }
378 } 454 }
379 455
380 class QuitCommand extends Command { 456 class QuitCommand extends Command {
381 final name = 'quit'; 457 final name = 'quit';
382 final helpShort = 'Quit the debugger.'; 458 final helpShort = 'Quit the debugger.';
383 void printHelp(Debugger debugger, List<String> args) { 459 void printHelp(Debugger debugger, List<String> args) {
384 debugger.cmdo.print(''' 460 debugger.cmdo.print('''
385 ----- quit ----- 461 ----- quit -----
386 462
387 Quit the debugger. 463 Quit the debugger.
388 464
389 Usage: 465 Usage:
390 quit 466 quit
391 '''); 467 ''');
392 } 468 }
393 469
394 Future run(Debugger debugger, List<String> args) { 470 Future run(Debugger debugger, List<String> args) {
395 var cmdo = debugger.cmdo; 471 var cmdo = debugger.cmdo;
396 if (args.length > 1) { 472 if (args.length > 1) {
397 cmdo.print("Unexpected arguments to $name command."); 473 cmdo.print("Unexpected arguments to $name command.");
398 return new Future.value(); 474 return new Future.value();
399 } 475 }
400 return debugger.quit(); 476 return debugger.quit();
401 } 477 }
402 } 478 }
403
404 List<Command> commandList =
405 [ new AttachCommand(),
406 new DetachCommand(),
407 new HelpCommand(),
408 new IsolateCommand(),
409 new QuitCommand() ];
410
411 List<Command> matchCommand(String commandName, bool exactMatchWins) {
412 var matches = [];
413 for (var command in commandList) {
414 if (command.name.startsWith(commandName)) {
415 if (exactMatchWins && command.name == commandName) {
416 // Exact match
417 return [command];
418 } else {
419 matches.add(command);
420 }
421 }
422 }
423 return matches;
424 }
425
426 List<String> completeCommand(List<String> commandParts) {
427 var completions = new List<String>();
428 if (commandParts.length == 1) {
429 String prefix = commandParts[0];
430 for (var command in commandList) {
431 if (command.name.startsWith(prefix)) {
432 completions.add(command.name);
433 }
434 }
435 }
436 return completions;
437 }
OLDNEW
« no previous file with comments | « tools/ddbg_service/lib/commando.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698