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

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
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());
turnidge 2014/09/17 16:06:24 CommandList is now an object and owned by the Debu
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(' ')}"];
turnidge 2014/09/17 16:06:24 Commands can now implement command-specific comple
Cutch 2014/09/17 20:07:26 Nice!
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
206 class DetachCommand extends Command { 222 class CommandList {
207 final name = 'detach'; 223 List _commands = new List<Command>();
208 final helpShort = 'Detach from a running Dart VM';
209 void printHelp(Debugger debugger, List<String> args) {
210 cmdo.print('''
211 ----- detach -----
212 224
213 Detach from the Dart VM. 225 void register(Command cmd) {
214 226 _commands.add(cmd);
215 Usage:
216 detach
217 ''');
218 } 227 }
219 228
220 Future run(Debugger debugger, List<String> args) { 229 List<Command> match(String commandName, bool exactMatchWins) {
221 var cmdo = debugger.cmdo; 230 var matches = [];
222 if (args.length > 1) { 231 for (var command in _commands) {
223 cmdo.print('$name expects no arguments'); 232 if (command.name.startsWith(commandName)) {
224 return new Future.value(); 233 if (exactMatchWins && command.name == commandName) {
234 // Exact match
235 return [command];
236 } else {
237 matches.add(command);
238 }
239 }
225 } 240 }
226 if (debugger.vm == null) { 241 return matches;
227 cmdo.print('No VM is attached');
228 } else {
229 debugger.vm = null;
230 }
231 return new Future.value();
232 }
233 }
234
235 class HelpCommand extends Command {
236 final name = 'help';
237 final helpShort = 'Show a list of debugger commands';
238 void printHelp(Debugger debugger, List<String> args) {
239 debugger.cmdo.print('''
240 ----- help -----
241
242 Show a list of debugger commands or get more information about a
243 particular command.
244
245 Usage:
246 help
247 help <command>
248 ''');
249 } 242 }
250 243
251 Future run(Debugger debugger, List<String> args) { 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) {
252 var cmdo = debugger.cmdo; 256 var cmdo = debugger.cmdo;
253 if (args.length <= 1) { 257 if (args.length <= 1) {
254 cmdo.print("\nDebugger commands:\n"); 258 cmdo.print("\nDebugger commands:\n");
255 for (var command in commandList) { 259 for (var command in _commands) {
256 cmdo.print(' ${command.name.padRight(11)} ${command.helpShort}'); 260 cmdo.print(' ${command.name.padRight(11)} ${command.helpShort}');
257 } 261 }
258 cmdo.print("For more information about a particular command, type:\n\n" 262 cmdo.print("For more information about a particular command, type:\n\n"
259 " help <command>\n"); 263 " help <command>\n");
260 264
261 cmdo.print("Commands may be abbreviated: e.g. type 'h' for 'help.\n"); 265 cmdo.print("Commands may be abbreviated: e.g. type 'h' for 'help.\n");
262 } else { 266 } else {
263 var commandName = args[1]; 267 var commandName = args[1];
264 var matches = matchCommand(commandName, true); 268 var matches =match(commandName, true);
265 if (matches.length == 0) { 269 if (matches.length == 0) {
266 cmdo.print("Command '$commandName' not recognized. " 270 cmdo.print("Command '$commandName' not recognized. "
267 "Try 'help' for a list of commands."); 271 "Try 'help' for a list of commands.");
268 } else { 272 } else {
269 for (var command in matches) { 273 for (var command in matches) {
270 command.printHelp(debugger, args); 274 command.printHelp(debugger, args);
271 } 275 }
272 } 276 }
273 } 277 }
278 }
279 }
274 280
281 class DetachCommand extends Command {
282 final name = 'detach';
283 final helpShort = 'Detach from a running Dart VM';
284 void printHelp(Debugger debugger, List<String> args) {
285 cmdo.print('''
286 ----- detach -----
287
288 Detach from the Dart VM.
289
290 Usage:
291 detach
292 ''');
293 }
294
295 Future run(Debugger debugger, List<String> args) {
296 var cmdo = debugger.cmdo;
297 if (args.length > 1) {
298 cmdo.print('$name expects no arguments');
299 return new Future.value();
300 }
301 if (debugger.vm == null) {
302 cmdo.print('No VM is attached');
303 } else {
304 debugger.vm = null;
305 }
275 return new Future.value(); 306 return new Future.value();
276 } 307 }
277 } 308 }
278 309
279 class IsolateCommand extends Command { 310 class IsolateCommand extends Command {
280 final name = 'isolate'; 311 final name = 'isolate';
281 final helpShort = 'Isolate control'; 312 final helpShort = 'Isolate control';
282 void printHelp(Debugger debugger, List<String> args) { 313 void printHelp(Debugger debugger, List<String> args) {
283 debugger.cmdo.print(''' 314 debugger.cmdo.print('''
284 ----- isolate ----- 315 ----- isolate -----
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 } else if (isolate.loading) { 399 } else if (isolate.loading) {
369 // TODO(turnidge): This is weird in a command line debugger. 400 // TODO(turnidge): This is weird in a command line debugger.
370 sb.write('(not available)'); 401 sb.write('(not available)');
371 } 402 }
372 sb.write('\n'); 403 sb.write('\n');
373 } 404 }
374 cmdo.print(sb); 405 cmdo.print(sb);
375 }); 406 });
376 return new Future.value(); 407 return new Future.value();
377 } 408 }
409
410 List<String> complete(List<String> commandParts) {
411 if (commandParts.isEmpty) {
412 return ['$name ${commandParts.join(" ")}'];
413 } else {
414 var completions = _commands.complete(commandParts);
415 return completions.map((completion) {
416 return '$name $completion';
417 });
418 }
419 }
378 } 420 }
379 421
380 class QuitCommand extends Command { 422 class QuitCommand extends Command {
381 final name = 'quit'; 423 final name = 'quit';
382 final helpShort = 'Quit the debugger.'; 424 final helpShort = 'Quit the debugger.';
383 void printHelp(Debugger debugger, List<String> args) { 425 void printHelp(Debugger debugger, List<String> args) {
384 debugger.cmdo.print(''' 426 debugger.cmdo.print('''
385 ----- quit ----- 427 ----- quit -----
386 428
387 Quit the debugger. 429 Quit the debugger.
388 430
389 Usage: 431 Usage:
390 quit 432 quit
391 '''); 433 ''');
392 } 434 }
393 435
394 Future run(Debugger debugger, List<String> args) { 436 Future run(Debugger debugger, List<String> args) {
395 var cmdo = debugger.cmdo; 437 var cmdo = debugger.cmdo;
396 if (args.length > 1) { 438 if (args.length > 1) {
397 cmdo.print("Unexpected arguments to $name command."); 439 cmdo.print("Unexpected arguments to $name command.");
398 return new Future.value(); 440 return new Future.value();
399 } 441 }
400 return debugger.quit(); 442 return debugger.quit();
401 } 443 }
402 } 444 }
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
« tools/ddbg_service/lib/commando.dart ('K') | « tools/ddbg_service/lib/commando.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698