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

Side by Side Diff: tools/ddbg.dart

Issue 69343017: Add support for command-line editing to ddbg. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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 | « no previous file | tools/ddbg/lib/commando.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 // Simple interactive debugger shell that connects to the Dart VM's debugger 5 // Simple interactive debugger shell that connects to the Dart VM's debugger
6 // connection port. 6 // connection port.
7 7
8 import "dart:convert"; 8 import "dart:convert";
9 import "dart:io"; 9 import "dart:io";
10 import "dart:async"; 10 import "dart:async";
11 11
12 import "ddbg/lib/commando.dart";
13
12 14
13 Map<int, Completer> outstandingCommands; 15 Map<int, Completer> outstandingCommands;
14 16
15 Socket vmSock; 17 Socket vmSock;
16 String vmData; 18 String vmData;
17 var stdinSubscription; 19 Commando cmdo;
18 var vmSubscription; 20 var vmSubscription;
19 int seqNum = 0; 21 int seqNum = 0;
20 int isolate_id = -1; 22 int isolate_id = -1;
21 23
24 Process targetProcess;
25
22 final verbose = false; 26 final verbose = false;
23 final printMessages = false; 27 final printMessages = false;
24 28
25 // The location of the last paused event. 29 // The location of the last paused event.
26 Map pausedLocation = null; 30 Map pausedLocation = null;
27 31
28 32
29 void printHelp() { 33 void printHelp() {
30 print(""" 34 print("""
31 q Quit debugger shell 35 q Quit debugger shell
(...skipping 21 matching lines...) Expand all
53 li List ids of all isolates in the VM 57 li List ids of all isolates in the VM
54 i <id> Interrupt execution of given isolate id 58 i <id> Interrupt execution of given isolate id
55 h Print help 59 h Print help
56 """); 60 """);
57 } 61 }
58 62
59 63
60 void quitShell() { 64 void quitShell() {
61 vmSubscription.cancel(); 65 vmSubscription.cancel();
62 vmSock.close(); 66 vmSock.close();
63 stdinSubscription.cancel(); 67 cmdo.done();
64 } 68 }
65 69
66 70
67 Future sendCmd(Map<String, dynamic> cmd) { 71 Future sendCmd(Map<String, dynamic> cmd) {
68 var completer = new Completer(); 72 var completer = new Completer();
69 int id = cmd["id"]; 73 int id = cmd["id"];
70 outstandingCommands[id] = completer; 74 outstandingCommands[id] = completer;
71 if (verbose) { 75 if (verbose) {
72 print("sending: '${JSON.encode(cmd)}'"); 76 print("sending: '${JSON.encode(cmd)}'");
73 } 77 }
74 vmSock.write(JSON.encode(cmd)); 78 vmSock.write(JSON.encode(cmd));
75 return completer.future; 79 return completer.future;
76 } 80 }
77 81
82
83 typedef void HandlerType(Map response);
84
85 HandlerType showPromptAfter(void handler(Map response)) {
86 // Hide the command prompt immediately.
87 return (response) {
88 handler(response);
89 cmdo.show();
90 };
91 }
92
93
78 void processCommand(String cmdLine) { 94 void processCommand(String cmdLine) {
79 95
80 void huh() { 96 void huh() {
81 print("'$cmdLine' not understood, try h for help"); 97 print("'$cmdLine' not understood, try h for help");
82 } 98 }
83 99
84 seqNum++; 100 seqNum++;
101 cmdLine = cmdLine.trim();
85 var args = cmdLine.split(' '); 102 var args = cmdLine.split(' ');
86 if (args.length == 0) { 103 if (args.length == 0) {
87 return; 104 return;
88 } 105 }
89 var command = args[0]; 106 var command = args[0];
90 var simple_commands = 107 var simple_commands =
91 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'}; 108 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'};
92 if (simple_commands[command] != null) { 109 if (simple_commands[command] != null) {
93 var cmd = { "id": seqNum, 110 var cmd = { "id": seqNum,
94 "command": simple_commands[command], 111 "command": simple_commands[command],
95 "params": { "isolateId" : isolate_id } }; 112 "params": { "isolateId" : isolate_id } };
96 sendCmd(cmd).then((result) => handleGenericResponse(result)); 113 cmdo.hide();
114 sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
97 } else if (command == "bt") { 115 } else if (command == "bt") {
98 var cmd = { "id": seqNum, 116 var cmd = { "id": seqNum,
99 "command": "getStackTrace", 117 "command": "getStackTrace",
100 "params": { "isolateId" : isolate_id } }; 118 "params": { "isolateId" : isolate_id } };
101 sendCmd(cmd).then((result) => handleStackTraceResponse(result)); 119 cmdo.hide();
120 sendCmd(cmd).then(showPromptAfter(handleStackTraceResponse));
102 } else if (command == "ll") { 121 } else if (command == "ll") {
103 var cmd = { "id": seqNum, 122 var cmd = { "id": seqNum,
104 "command": "getLibraries", 123 "command": "getLibraries",
105 "params": { "isolateId" : isolate_id } }; 124 "params": { "isolateId" : isolate_id } };
106 sendCmd(cmd).then((result) => handleGetLibraryResponse(result)); 125 cmdo.hide();
126 sendCmd(cmd).then(showPromptAfter(handleGetLibraryResponse));
107 } else if (command == "sbp" && args.length >= 2) { 127 } else if (command == "sbp" && args.length >= 2) {
108 var url, line; 128 var url, line;
109 if (args.length == 2 && pausedLocation != null) { 129 if (args.length == 2 && pausedLocation != null) {
110 url = pausedLocation["url"]; 130 url = pausedLocation["url"];
111 assert(url != null); 131 assert(url != null);
112 line = int.parse(args[1]); 132 line = int.parse(args[1]);
113 } else { 133 } else {
114 url = args[1]; 134 url = args[1];
115 line = int.parse(args[2]); 135 line = int.parse(args[2]);
116 } 136 }
117 var cmd = { "id": seqNum, 137 var cmd = { "id": seqNum,
118 "command": "setBreakpoint", 138 "command": "setBreakpoint",
119 "params": { "isolateId" : isolate_id, 139 "params": { "isolateId" : isolate_id,
120 "url": url, 140 "url": url,
121 "line": line }}; 141 "line": line }};
122 sendCmd(cmd).then((result) => handleSetBpResponse(result)); 142 cmdo.hide();
143 sendCmd(cmd).then(showPromptAfter(handleSetBpResponse));
123 } else if (command == "rbp" && args.length == 2) { 144 } else if (command == "rbp" && args.length == 2) {
124 var cmd = { "id": seqNum, 145 var cmd = { "id": seqNum,
125 "command": "removeBreakpoint", 146 "command": "removeBreakpoint",
126 "params": { "isolateId" : isolate_id, 147 "params": { "isolateId" : isolate_id,
127 "breakpointId": int.parse(args[1]) } }; 148 "breakpointId": int.parse(args[1]) } };
128 sendCmd(cmd).then((result) => handleGenericResponse(result)); 149 cmdo.hide();
150 sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
129 } else if (command == "ls" && args.length == 2) { 151 } else if (command == "ls" && args.length == 2) {
130 var cmd = { "id": seqNum, 152 var cmd = { "id": seqNum,
131 "command": "getScriptURLs", 153 "command": "getScriptURLs",
132 "params": { "isolateId" : isolate_id, 154 "params": { "isolateId" : isolate_id,
133 "libraryId": int.parse(args[1]) } }; 155 "libraryId": int.parse(args[1]) } };
134 sendCmd(cmd).then((result) => handleGetScriptsResponse(result)); 156 cmdo.hide();
157 sendCmd(cmd).then(showPromptAfter(handleGetScriptsResponse));
135 } else if (command == "eval" && args.length > 3) { 158 } else if (command == "eval" && args.length > 3) {
136 var expr = args.getRange(3, args.length).join(" "); 159 var expr = args.getRange(3, args.length).join(" ");
137 var target = args[1]; 160 var target = args[1];
138 if (target == "obj") { 161 if (target == "obj") {
139 target = "objectId"; 162 target = "objectId";
140 } else if (target == "cls") { 163 } else if (target == "cls") {
141 target = "classId"; 164 target = "classId";
142 } else if (target == "lib") { 165 } else if (target == "lib") {
143 target = "libraryId"; 166 target = "libraryId";
144 } else { 167 } else {
145 huh(); 168 huh();
146 return; 169 return;
147 } 170 }
148 var cmd = { "id": seqNum, 171 var cmd = { "id": seqNum,
149 "command": "evaluateExpr", 172 "command": "evaluateExpr",
150 "params": { "isolateId": isolate_id, 173 "params": { "isolateId": isolate_id,
151 target: int.parse(args[2]), 174 target: int.parse(args[2]),
152 "expression": expr } }; 175 "expression": expr } };
153 sendCmd(cmd).then((result) => handleEvalResponse(result)); 176 cmdo.hide();
177 sendCmd(cmd).then(showPromptAfter(handleEvalResponse));
154 } else if (command == "po" && args.length == 2) { 178 } else if (command == "po" && args.length == 2) {
155 var cmd = { "id": seqNum, 179 var cmd = { "id": seqNum,
156 "command": "getObjectProperties", 180 "command": "getObjectProperties",
157 "params": { "isolateId" : isolate_id, 181 "params": { "isolateId" : isolate_id,
158 "objectId": int.parse(args[1]) } }; 182 "objectId": int.parse(args[1]) } };
159 sendCmd(cmd).then((result) => handleGetObjPropsResponse(result)); 183 cmdo.hide();
184 sendCmd(cmd).then(showPromptAfter(handleGetObjPropsResponse));
160 } else if (command == "pl" && args.length >= 3) { 185 } else if (command == "pl" && args.length >= 3) {
161 var cmd; 186 var cmd;
162 if (args.length == 3) { 187 if (args.length == 3) {
163 cmd = { "id": seqNum, 188 cmd = { "id": seqNum,
164 "command": "getListElements", 189 "command": "getListElements",
165 "params": { "isolateId" : isolate_id, 190 "params": { "isolateId" : isolate_id,
166 "objectId": int.parse(args[1]), 191 "objectId": int.parse(args[1]),
167 "index": int.parse(args[2]) } }; 192 "index": int.parse(args[2]) } };
168 } else { 193 } else {
169 cmd = { "id": seqNum, 194 cmd = { "id": seqNum,
170 "command": "getListElements", 195 "command": "getListElements",
171 "params": { "isolateId" : isolate_id, 196 "params": { "isolateId" : isolate_id,
172 "objectId": int.parse(args[1]), 197 "objectId": int.parse(args[1]),
173 "index": int.parse(args[2]), 198 "index": int.parse(args[2]),
174 "length": int.parse(args[3]) } }; 199 "length": int.parse(args[3]) } };
175 } 200 }
176 sendCmd(cmd).then((result) => handleGetListResponse(result)); 201 cmdo.hide();
202 sendCmd(cmd).then(showPromptAfter(handleGetListResponse));
177 } else if (command == "pc" && args.length == 2) { 203 } else if (command == "pc" && args.length == 2) {
178 var cmd = { "id": seqNum, 204 var cmd = { "id": seqNum,
179 "command": "getClassProperties", 205 "command": "getClassProperties",
180 "params": { "isolateId" : isolate_id, 206 "params": { "isolateId" : isolate_id,
181 "classId": int.parse(args[1]) } }; 207 "classId": int.parse(args[1]) } };
182 sendCmd(cmd).then((result) => handleGetClassPropsResponse(result)); 208 cmdo.hide();
209 sendCmd(cmd).then(showPromptAfter(handleGetClassPropsResponse));
183 } else if (command == "plib" && args.length == 2) { 210 } else if (command == "plib" && args.length == 2) {
184 var cmd = { "id": seqNum, 211 var cmd = { "id": seqNum,
185 "command": "getLibraryProperties", 212 "command": "getLibraryProperties",
186 "params": {"isolateId" : isolate_id, 213 "params": {"isolateId" : isolate_id,
187 "libraryId": int.parse(args[1]) } }; 214 "libraryId": int.parse(args[1]) } };
188 sendCmd(cmd).then((result) => handleGetLibraryPropsResponse(result)); 215 cmdo.hide();
216 sendCmd(cmd).then(showPromptAfter(handleGetLibraryPropsResponse));
189 } else if (command == "slib" && args.length == 3) { 217 } else if (command == "slib" && args.length == 3) {
190 var cmd = { "id": seqNum, 218 var cmd = { "id": seqNum,
191 "command": "setLibraryProperties", 219 "command": "setLibraryProperties",
192 "params": {"isolateId" : isolate_id, 220 "params": {"isolateId" : isolate_id,
193 "libraryId": int.parse(args[1]), 221 "libraryId": int.parse(args[1]),
194 "debuggingEnabled": args[2] } }; 222 "debuggingEnabled": args[2] } };
195 sendCmd(cmd).then((result) => handleSetLibraryPropsResponse(result)); 223 cmdo.hide();
224 sendCmd(cmd).then(showPromptAfter(handleSetLibraryPropsResponse));
196 } else if (command == "pg" && args.length == 2) { 225 } else if (command == "pg" && args.length == 2) {
197 var cmd = { "id": seqNum, 226 var cmd = { "id": seqNum,
198 "command": "getGlobalVariables", 227 "command": "getGlobalVariables",
199 "params": { "isolateId" : isolate_id, 228 "params": { "isolateId" : isolate_id,
200 "libraryId": int.parse(args[1]) } }; 229 "libraryId": int.parse(args[1]) } };
201 sendCmd(cmd).then((result) => handleGetGlobalVarsResponse(result)); 230 cmdo.hide();
231 sendCmd(cmd).then(showPromptAfter(handleGetGlobalVarsResponse));
202 } else if (command == "gs" && args.length == 3) { 232 } else if (command == "gs" && args.length == 3) {
203 var cmd = { "id": seqNum, 233 var cmd = { "id": seqNum,
204 "command": "getScriptSource", 234 "command": "getScriptSource",
205 "params": { "isolateId" : isolate_id, 235 "params": { "isolateId" : isolate_id,
206 "libraryId": int.parse(args[1]), 236 "libraryId": int.parse(args[1]),
207 "url": args[2] } }; 237 "url": args[2] } };
208 sendCmd(cmd).then((result) => handleGetSourceResponse(result)); 238 cmdo.hide();
239 sendCmd(cmd).then(showPromptAfter(handleGetSourceResponse));
209 } else if (command == "tok" && args.length == 3) { 240 } else if (command == "tok" && args.length == 3) {
210 var cmd = { "id": seqNum, 241 var cmd = { "id": seqNum,
211 "command": "getLineNumberTable", 242 "command": "getLineNumberTable",
212 "params": { "isolateId" : isolate_id, 243 "params": { "isolateId" : isolate_id,
213 "libraryId": int.parse(args[1]), 244 "libraryId": int.parse(args[1]),
214 "url": args[2] } }; 245 "url": args[2] } };
215 sendCmd(cmd).then((result) => handleGetLineTableResponse(result)); 246 cmdo.hide();
247 sendCmd(cmd).then(showPromptAfter(handleGetLineTableResponse));
216 } else if (command == "epi" && args.length == 2) { 248 } else if (command == "epi" && args.length == 2) {
217 var cmd = { "id": seqNum, 249 var cmd = { "id": seqNum,
218 "command": "setPauseOnException", 250 "command": "setPauseOnException",
219 "params": { "isolateId" : isolate_id, 251 "params": { "isolateId" : isolate_id,
220 "exceptions": args[1] } }; 252 "exceptions": args[1] } };
221 sendCmd(cmd).then((result) => handleGenericResponse(result)); 253 cmdo.hide();
254 sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
222 } else if (command == "li") { 255 } else if (command == "li") {
223 var cmd = { "id": seqNum, "command": "getIsolateIds" }; 256 var cmd = { "id": seqNum, "command": "getIsolateIds" };
224 sendCmd(cmd).then((result) => handleGetIsolatesResponse(result)); 257 cmdo.hide();
258 sendCmd(cmd).then(showPromptAfter(handleGetIsolatesResponse));
225 } else if (command == "i" && args.length == 2) { 259 } else if (command == "i" && args.length == 2) {
226 var cmd = { "id": seqNum, 260 var cmd = { "id": seqNum,
227 "command": "interrupt", 261 "command": "interrupt",
228 "params": { "isolateId": int.parse(args[1]) } }; 262 "params": { "isolateId": int.parse(args[1]) } };
229 sendCmd(cmd).then((result) => handleGenericResponse(result)); 263 cmdo.hide();
264 sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
230 } else if (command == "q") { 265 } else if (command == "q") {
231 quitShell(); 266 quitShell();
232 } else if (command == "h") { 267 } else if (command == "h") {
233 printHelp(); 268 printHelp();
234 } else { 269 } else {
235 huh(); 270 huh();
236 } 271 }
237 } 272 }
238 273
239 274
(...skipping 22 matching lines...) Expand all
262 } 297 }
263 298
264 299
265 printNamedObject(obj) { 300 printNamedObject(obj) {
266 var name = obj["name"]; 301 var name = obj["name"];
267 var value = obj["value"]; 302 var value = obj["value"];
268 print(" $name = ${remoteObject(value)}"); 303 print(" $name = ${remoteObject(value)}");
269 } 304 }
270 305
271 306
272 handleGetObjPropsResponse(response) { 307 handleGetObjPropsResponse(Map response) {
273 Map props = response["result"]; 308 Map props = response["result"];
274 int class_id = props["classId"]; 309 int class_id = props["classId"];
275 if (class_id == -1) { 310 if (class_id == -1) {
276 print(" null"); 311 print(" null");
277 return; 312 return;
278 } 313 }
279 List fields = props["fields"]; 314 List fields = props["fields"];
280 print(" class id: $class_id"); 315 print(" class id: $class_id");
281 for (int i = 0; i < fields.length; i++) { 316 for (int i = 0; i < fields.length; i++) {
282 printNamedObject(fields[i]); 317 printNamedObject(fields[i]);
283 } 318 }
284 } 319 }
285 320
286 handleGetListResponse(response) { 321 handleGetListResponse(Map response) {
287 Map result = response["result"]; 322 Map result = response["result"];
288 if (result["elements"] != null) { 323 if (result["elements"] != null) {
289 // List slice. 324 // List slice.
290 var index = result["index"]; 325 var index = result["index"];
291 var length = result["length"]; 326 var length = result["length"];
292 List elements = result["elements"]; 327 List elements = result["elements"];
293 assert(length == elements.length); 328 assert(length == elements.length);
294 for (int i = 0; i < length; i++) { 329 for (int i = 0; i < length; i++) {
295 var kind = elements[i]["kind"]; 330 var kind = elements[i]["kind"];
296 var text = elements[i]["text"]; 331 var text = elements[i]["text"];
297 print(" ${index + i}: ($kind) $text"); 332 print(" ${index + i}: ($kind) $text");
298 } 333 }
299 } else { 334 } else {
300 // One element, a remote object. 335 // One element, a remote object.
301 print(result); 336 print(result);
302 print(" ${remoteObject(result)}"); 337 print(" ${remoteObject(result)}");
303 } 338 }
304 } 339 }
305 340
306 341
307 handleGetClassPropsResponse(response) { 342 handleGetClassPropsResponse(Map response) {
308 Map props = response["result"]; 343 Map props = response["result"];
309 assert(props["name"] != null); 344 assert(props["name"] != null);
310 int libId = props["libraryId"]; 345 int libId = props["libraryId"];
311 assert(libId != null); 346 assert(libId != null);
312 print(" class ${props["name"]} (library id: $libId)"); 347 print(" class ${props["name"]} (library id: $libId)");
313 List fields = props["fields"]; 348 List fields = props["fields"];
314 if (fields.length > 0) { 349 if (fields.length > 0) {
315 print(" static fields:"); 350 print(" static fields:");
316 for (int i = 0; i < fields.length; i++) { 351 for (int i = 0; i < fields.length; i++) {
317 printNamedObject(fields[i]); 352 printNamedObject(fields[i]);
318 } 353 }
319 } 354 }
320 } 355 }
321 356
322 357
323 handleGetLibraryPropsResponse(response) { 358 handleGetLibraryPropsResponse(Map response) {
324 Map props = response["result"]; 359 Map props = response["result"];
325 assert(props["url"] != null); 360 assert(props["url"] != null);
326 print(" library url: ${props["url"]}"); 361 print(" library url: ${props["url"]}");
327 assert(props["debuggingEnabled"] != null); 362 assert(props["debuggingEnabled"] != null);
328 print(" debugging enabled: ${props["debuggingEnabled"]}"); 363 print(" debugging enabled: ${props["debuggingEnabled"]}");
329 List imports = props["imports"]; 364 List imports = props["imports"];
330 assert(imports != null); 365 assert(imports != null);
331 if (imports.length > 0) { 366 if (imports.length > 0) {
332 print(" imports:"); 367 print(" imports:");
333 for (int i = 0; i < imports.length; i++) { 368 for (int i = 0; i < imports.length; i++) {
334 print(" id ${imports[i]["libraryId"]} prefix ${imports[i]["prefix"]}"); 369 print(" id ${imports[i]["libraryId"]} prefix ${imports[i]["prefix"]}");
335 } 370 }
336 } 371 }
337 List globals = props["globals"]; 372 List globals = props["globals"];
338 assert(globals != null); 373 assert(globals != null);
339 if (globals.length > 0) { 374 if (globals.length > 0) {
340 print(" global variables:"); 375 print(" global variables:");
341 for (int i = 0; i < globals.length; i++) { 376 for (int i = 0; i < globals.length; i++) {
342 printNamedObject(globals[i]); 377 printNamedObject(globals[i]);
343 } 378 }
344 } 379 }
345 } 380 }
346 381
347 382
348 handleSetLibraryPropsResponse(response) { 383 handleSetLibraryPropsResponse(Map response) {
349 Map props = response["result"]; 384 Map props = response["result"];
350 assert(props["debuggingEnabled"] != null); 385 assert(props["debuggingEnabled"] != null);
351 print(" debugging enabled: ${props["debuggingEnabled"]}"); 386 print(" debugging enabled: ${props["debuggingEnabled"]}");
352 } 387 }
353 388
354 389
355 handleGetGlobalVarsResponse(response) { 390 handleGetGlobalVarsResponse(Map response) {
356 List globals = response["result"]["globals"]; 391 List globals = response["result"]["globals"];
357 for (int i = 0; i < globals.length; i++) { 392 for (int i = 0; i < globals.length; i++) {
358 printNamedObject(globals[i]); 393 printNamedObject(globals[i]);
359 } 394 }
360 } 395 }
361 396
362 397
363 handleGetSourceResponse(response) { 398 handleGetSourceResponse(Map response) {
364 Map result = response["result"]; 399 Map result = response["result"];
365 String source = result["text"]; 400 String source = result["text"];
366 print("Source text:\n$source\n--------"); 401 print("Source text:\n$source\n--------");
367 } 402 }
368 403
369 404
370 handleGetLineTableResponse(response) { 405 handleGetLineTableResponse(Map response) {
371 Map result = response["result"]; 406 Map result = response["result"];
372 var info = result["lines"]; 407 var info = result["lines"];
373 print("Line info table:\n$info"); 408 print("Line info table:\n$info");
374 } 409 }
375 410
376 411
377 handleGetIsolatesResponse(response) { 412 void handleGetIsolatesResponse(Map response) {
378 Map result = response["result"]; 413 Map result = response["result"];
379 print("Isolates: ${result["isolateIds"]}"); 414 print("Isolates: ${result["isolateIds"]}");
380 } 415 }
381 416
382 417
383 void handleGetLibraryResponse(response) { 418 void handleGetLibraryResponse(Map response) {
384 Map result = response["result"]; 419 Map result = response["result"];
385 List libs = result["libraries"]; 420 List libs = result["libraries"];
386 print("Loaded libraries:"); 421 print("Loaded libraries:");
387 print(libs); 422 print(libs);
388 for (int i = 0; i < libs.length; i++) { 423 for (int i = 0; i < libs.length; i++) {
389 print(" ${libs[i]["id"]} ${libs[i]["url"]}"); 424 print(" ${libs[i]["id"]} ${libs[i]["url"]}");
390 } 425 }
391 } 426 }
392 427
393 428
394 void handleGetScriptsResponse(response) { 429 void handleGetScriptsResponse(Map response) {
395 Map result = response["result"]; 430 Map result = response["result"];
396 List urls = result["urls"]; 431 List urls = result["urls"];
397 print("Loaded scripts:"); 432 print("Loaded scripts:");
398 for (int i = 0; i < urls.length; i++) { 433 for (int i = 0; i < urls.length; i++) {
399 print(" $i ${urls[i]}"); 434 print(" $i ${urls[i]}");
400 } 435 }
401 } 436 }
402 437
403 438
404 void handleEvalResponse(response) { 439 void handleEvalResponse(Map response) {
405 Map result = response["result"]; 440 Map result = response["result"];
406 print(remoteObject(result)); 441 print(remoteObject(result));
407 } 442 }
408 443
409 444
410 void handleSetBpResponse(response) { 445 void handleSetBpResponse(Map response) {
411 Map result = response["result"]; 446 Map result = response["result"];
412 var id = result["breakpointId"]; 447 var id = result["breakpointId"];
413 assert(id != null); 448 assert(id != null);
414 print("Set BP $id"); 449 print("Set BP $id");
415 } 450 }
416 451
417 452
418 void handleGenericResponse(response) { 453 void handleGenericResponse(Map response) {
419 if (response["error"] != null) { 454 if (response["error"] != null) {
420 print("Error: ${response["error"]}"); 455 print("Error: ${response["error"]}");
421 } 456 }
422 } 457 }
423 458
424 459
425 void handleStackTraceResponse(response) { 460 void handleStackTraceResponse(Map response) {
426 Map result = response["result"]; 461 Map result = response["result"];
427 List callFrames = result["callFrames"]; 462 List callFrames = result["callFrames"];
428 assert(callFrames != null); 463 assert(callFrames != null);
429 printStackTrace(callFrames); 464 printStackTrace(callFrames);
430 } 465 }
431 466
432 467
433 void printStackFrame(frame_num, Map frame) { 468 void printStackFrame(frame_num, Map frame) {
434 var fname = frame["functionName"]; 469 var fname = frame["functionName"];
435 var libId = frame["location"]["libraryId"]; 470 var libId = frame["location"]["libraryId"];
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } 506 }
472 507
473 508
474 void processVmMessage(String jsonString) { 509 void processVmMessage(String jsonString) {
475 var msg = JSON.decode(jsonString); 510 var msg = JSON.decode(jsonString);
476 if (msg == null) { 511 if (msg == null) {
477 return; 512 return;
478 } 513 }
479 var event = msg["event"]; 514 var event = msg["event"];
480 if (event == "paused") { 515 if (event == "paused") {
516 cmdo.hide();
481 handlePausedEvent(msg); 517 handlePausedEvent(msg);
518 cmdo.show();
482 return; 519 return;
483 } 520 }
484 if (event == "breakpointResolved") { 521 if (event == "breakpointResolved") {
485 Map params = msg["params"]; 522 Map params = msg["params"];
486 assert(params != null); 523 assert(params != null);
524 cmdo.hide();
487 print("BP ${params["breakpointId"]} resolved and " 525 print("BP ${params["breakpointId"]} resolved and "
488 "set at line ${params["line"]}."); 526 "set at line ${params["line"]}.");
527 cmdo.show();
489 return; 528 return;
490 } 529 }
491 if (event == "isolate") { 530 if (event == "isolate") {
492 Map params = msg["params"]; 531 Map params = msg["params"];
493 assert(params != null); 532 assert(params != null);
533 cmdo.hide();
494 print("Isolate ${params["id"]} has been ${params["reason"]}."); 534 print("Isolate ${params["id"]} has been ${params["reason"]}.");
535 cmdo.show();
495 return; 536 return;
496 } 537 }
497 if (msg["id"] != null) { 538 if (msg["id"] != null) {
498 var id = msg["id"]; 539 var id = msg["id"];
499 if (outstandingCommands.containsKey(id)) { 540 if (outstandingCommands.containsKey(id)) {
541 var completer = outstandingCommands.remove(id);
500 if (msg["error"] != null) { 542 if (msg["error"] != null) {
501 print("VM says: ${msg["error"]}"); 543 print("VM says: ${msg["error"]}");
544 // TODO(turnidge): Rework how hide/show happens. For now we
545 // show here explicitly.
546 cmdo.show();
502 } else { 547 } else {
503 var completer = outstandingCommands[id];
504 completer.complete(msg); 548 completer.complete(msg);
505 } 549 }
506 outstandingCommands.remove(id);
507 } 550 }
508 } 551 }
509 } 552 }
510 553
511 bool haveGarbageVmData() { 554 bool haveGarbageVmData() {
512 if (vmData == null || vmData.length == 0) return false; 555 if (vmData == null || vmData.length == 0) return false;
513 var i = 0, char = " "; 556 var i = 0, char = " ";
514 while (i < vmData.length) { 557 while (i < vmData.length) {
515 char = vmData[i]; 558 char = vmData[i];
516 if (char != " " && char != "\n" && char != "\r" && char != "\t") break; 559 if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 nesting--; 644 nesting--;
602 if (nesting == 0) return index; 645 if (nesting == 0) return index;
603 } else if (char == '"') { 646 } else if (char == '"') {
604 // Strings can contain braces. Skip their content. 647 // Strings can contain braces. Skip their content.
605 index = skipString(index); 648 index = skipString(index);
606 } 649 }
607 } 650 }
608 return 0; 651 return 0;
609 } 652 }
610 653
654 List<String> debuggerCommandCompleter(List<String> commandParts) {
655 List<String> completions = new List<String>();
656
657 // TODO(turnidge): Have a global command table and use it to for
658 // help messages, command completion, and command dispatching. For now
659 // we hardcode the list here.
660 //
661 // TODO(turnidge): Implement completion for arguments as well.
662 List<String> allCommands = ['q', 'bt', 'r', 's', 'so', 'si', 'sbp', 'rbp',
663 'po', 'eval', 'pl', 'pc', 'll', 'plib', 'slib',
664 'pg', 'ls', 'gs', 'tok', 'epi', 'li', 'i', 'h'];
665
666 // Completion of first word in the command.
667 if (commandParts.length == 1) {
668 String prefix = commandParts.last;
669 for (String command in allCommands) {
670 if (command.startsWith(prefix)) {
671 completions.add(command);
672 }
673 }
674 }
675
676 return completions;
677 }
611 678
612 void debuggerMain() { 679 void debuggerMain() {
613 outstandingCommands = new Map<int, Completer>(); 680 outstandingCommands = new Map<int, Completer>();
614 Socket.connect("127.0.0.1", 5858).then((s) { 681 Socket.connect("127.0.0.1", 5858).then((s) {
615 vmSock = s; 682 vmSock = s;
616 vmSock.setOption(SocketOption.TCP_NODELAY, true); 683 vmSock.setOption(SocketOption.TCP_NODELAY, true);
617 var stringStream = vmSock.transform(UTF8.decoder); 684 var stringStream = vmSock.transform(UTF8.decoder);
618 vmSubscription = stringStream.listen( 685 vmSubscription = stringStream.listen(
619 (String data) { 686 (String data) {
620 processVmData(data); 687 processVmData(data);
621 }, 688 },
622 onDone: () { 689 onDone: () {
623 print("VM debugger connection closed"); 690 print("VM debugger connection closed");
624 quitShell(); 691 quitShell();
625 }, 692 },
626 onError: (err) { 693 onError: (err) {
627 print("Error in debug connection: $err"); 694 print("Error in debug connection: $err");
628 // TODO(floitsch): do we want to print the stack trace? 695 // TODO(floitsch): do we want to print the stack trace?
629 quitShell(); 696 quitShell();
630 }); 697 });
631 stdinSubscription = stdin.transform(UTF8.decoder) 698 cmdo = new Commando(stdin, stdout, processCommand,
632 .transform(new LineSplitter()) 699 completer : debuggerCommandCompleter);
633 .listen((String line) => processCommand(line));
634 }); 700 });
635 } 701 }
636 702
637 void main(List<String> arguments) { 703 void main(List<String> args) {
638 if (arguments.length > 0) { 704 if (args.length > 0) {
639 arguments = <String>['--debug', '--verbose_debug']..addAll(arguments); 705 if (verbose) {
640 Process.start(Platform.executable, arguments).then((Process process) { 706 args = <String>['--debug', '--verbose_debug']..addAll(args);
641 process.stdin.close(); 707 } else {
642 process.exitCode.then((int exitCode) { 708 args = <String>['--debug']..addAll(args);
643 print('${arguments.join(" ")} exited with $exitCode'); 709 }
644 }); 710 Process.start(Platform.executable, args).then((Process process) {
711 targetProcess = process;
712 process.stdin.close();
713
714 // TODO(turnidge): For now we only show full lines of output
715 // from the debugged process. Should show each character.
716 process.stdout
717 .transform(UTF8.decoder)
718 .transform(new LineSplitter())
719 .listen((String line) {
720 // Hide/show command prompt across asynchronous output.
721 if (cmdo != null) {
722 cmdo.hide();
723 }
724 print("$line");
725 if (cmdo != null) {
726 cmdo.show();
727 }
728 });
729
730 process.exitCode.then((int exitCode) {
731 if (exitCode == 0) {
732 print('Program exited normally.');
733 } else {
734 print('Program exited with code $exitCode.');
735 }
736 });
737
645 debuggerMain(); 738 debuggerMain();
646 }); 739 });
647 } else { 740 } else {
648 debuggerMain(); 741 debuggerMain();
649 } 742 }
650 } 743 }
OLDNEW
« no previous file with comments | « no previous file | tools/ddbg/lib/commando.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698