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

Side by Side Diff: tests/standalone/debugger/debug_lib.dart

Issue 15295014: Always send kill signal to debug target (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « no previous file | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 used by debugger wire protocol tests (standalone VM debugging). 5 // Library used by debugger wire protocol tests (standalone VM debugging).
6 6
7 library DartDebugger; 7 library DartDebugger;
8 8
9 import "dart:async"; 9 import "dart:async";
10 import "dart:io"; 10 import "dart:io";
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 172
173 void send(Debugger debugger) { 173 void send(Debugger debugger) {
174 debugger.sendMessage(template); 174 debugger.sendMessage(template);
175 } 175 }
176 176
177 void matchResponse(Debugger debugger) { 177 void matchResponse(Debugger debugger) {
178 Map response = debugger.currentMessage; 178 Map response = debugger.currentMessage;
179 var id = template["id"]; 179 var id = template["id"];
180 assert(id != null && id >= 0); 180 assert(id != null && id >= 0);
181 if (response["id"] != id) { 181 if (response["id"] != id) {
182 debugger.error("Expected messaged id $id but got ${response["id"]}."); 182 debugger.error("Error: expected messaged id $id but got ${response["id"]}. ");
183 } 183 }
184 } 184 }
185 } 185 }
186 186
187 187
188 class FrameMatcher extends Command { 188 class FrameMatcher extends Command {
189 int frameIndex; 189 int frameIndex;
190 List<String> functionNames; 190 List<String> functionNames;
191 191
192 FrameMatcher(this.frameIndex, this.functionNames) { 192 FrameMatcher(this.frameIndex, this.functionNames) {
193 template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}} ; 193 template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}} ;
194 } 194 }
195 195
196 void matchResponse(Debugger debugger) { 196 void matchResponse(Debugger debugger) {
197 super.matchResponse(debugger); 197 super.matchResponse(debugger);
198 var msg = debugger.currentMessage; 198 var msg = debugger.currentMessage;
199 List frames = getJsonValue(msg, "result:callFrames"); 199 List frames = getJsonValue(msg, "result:callFrames");
200 assert(frames != null); 200 assert(frames != null);
201 if (debugger.scriptUrl == null) { 201 if (debugger.scriptUrl == null) {
202 var name = frames[0]["functionName"]; 202 var name = frames[0]["functionName"];
203 if (name == "main") { 203 if (name == "main") {
204 // Extract script url of debugged script. 204 // Extract script url of debugged script.
205 debugger.scriptUrl = frames[0]["location"]["url"]; 205 debugger.scriptUrl = frames[0]["location"]["url"];
206 assert(debugger.scriptUrl != null); 206 assert(debugger.scriptUrl != null);
207 } 207 }
208 } 208 }
209 if (frames.length < functionNames.length) { 209 if (frames.length < functionNames.length) {
210 debugger.error("stack trace not long enough " 210 debugger.error("Error: stack trace not long enough "
211 "to match ${functionNames.length} frames"); 211 "to match ${functionNames.length} frames");
212 return; 212 return;
213 } 213 }
214 for (int i = 0; i < functionNames.length; i++) { 214 for (int i = 0; i < functionNames.length; i++) {
215 var idx = i + frameIndex; 215 var idx = i + frameIndex;
216 var name = frames[idx]["functionName"]; 216 var name = frames[idx]["functionName"];
217 assert(name != null); 217 assert(name != null);
218 if (name != functionNames[i]) { 218 if (name != functionNames[i]) {
219 debugger.error("call frame $idx: " 219 debugger.error("Error: call frame $idx: "
220 "expected function name '${functionNames[i]}' but found '$name'"); 220 "expected function name '${functionNames[i]}' but found '$name'");
221 return; 221 return;
222 } 222 }
223 } 223 }
224 } 224 }
225 } 225 }
226 226
227 227
228 MatchFrame(int frameIndex, String functionName) { 228 MatchFrame(int frameIndex, String functionName) {
229 return new FrameMatcher(frameIndex, [ functionName ]); 229 return new FrameMatcher(frameIndex, [ functionName ]);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // Debug target process properties. 298 // Debug target process properties.
299 Process targetProcess; 299 Process targetProcess;
300 int portNumber; 300 int portNumber;
301 Socket socket; 301 Socket socket;
302 JsonBuffer responses = new JsonBuffer(); 302 JsonBuffer responses = new JsonBuffer();
303 303
304 DebugScript script; 304 DebugScript script;
305 int seqNr = 0; // Sequence number of next debugger command message. 305 int seqNr = 0; // Sequence number of next debugger command message.
306 Command lastCommand = null; // Most recent command sent to target. 306 Command lastCommand = null; // Most recent command sent to target.
307 List<String> errors = new List(); 307 List<String> errors = new List();
308 bool cleanupDone = false;
308 309
309 // Data collected from debug target. 310 // Data collected from debug target.
310 Map currentMessage = null; // Currently handled message sent by target. 311 Map currentMessage = null; // Currently handled message sent by target.
311 String scriptUrl = null; 312 String scriptUrl = null;
312 bool shutdownEventSeen = false; 313 bool shutdownEventSeen = false;
313 int isolateId = 0; 314 int isolateId = 0;
314 bool isPaused = false; 315 bool isPaused = false;
315 316
316 Debugger(this.targetProcess, this.portNumber, this.script) { 317 Debugger(this.targetProcess, this.portNumber, this.script) {
317 stdin.listen((_) {}); 318 stdin.listen((_) {});
(...skipping 19 matching lines...) Expand all
337 void handleEvent(Map<String,dynamic> msg) { 338 void handleEvent(Map<String,dynamic> msg) {
338 if (msg["event"] == "isolate") { 339 if (msg["event"] == "isolate") {
339 if (msg["params"]["reason"] == "created") { 340 if (msg["params"]["reason"] == "created") {
340 isolateId = msg["params"]["id"]; 341 isolateId = msg["params"]["id"];
341 assert(isolateId != null); 342 assert(isolateId != null);
342 print("Debuggee isolate id $isolateId created."); 343 print("Debuggee isolate id $isolateId created.");
343 } else if (msg["params"]["reason"] == "shutdown") { 344 } else if (msg["params"]["reason"] == "shutdown") {
344 print("Debuggee isolate id ${msg["params"]["id"]} shut down."); 345 print("Debuggee isolate id ${msg["params"]["id"]} shut down.");
345 shutdownEventSeen = true; 346 shutdownEventSeen = true;
346 if (!script.isEmpty) { 347 if (!script.isEmpty) {
347 error("Premature isolate shutdown event seen."); 348 error("Error: premature isolate shutdown event seen.");
348 } 349 }
349 } 350 }
350 } else if (msg["event"] == "breakpointResolved") { 351 } else if (msg["event"] == "breakpointResolved") {
351 var bpId = msg["params"]["breakpointId"]; 352 var bpId = msg["params"]["breakpointId"];
352 assert(bpId != null); 353 assert(bpId != null);
353 var isolateId = msg["params"]["isolateId"]; 354 var isolateId = msg["params"]["isolateId"];
354 assert(isolateId != null); 355 assert(isolateId != null);
355 var location = msg["params"]["location"]; 356 var location = msg["params"]["location"];
356 assert(location != null); 357 assert(location != null);
357 print("Isolate $isolateId: breakpoint $bpId resolved" 358 print("Isolate $isolateId: breakpoint $bpId resolved"
358 " at location $location"); 359 " at location $location");
359 // We may want to maintain a table of breakpoints in the future. 360 // We may want to maintain a table of breakpoints in the future.
360 } else if (msg["event"] == "paused") { 361 } else if (msg["event"] == "paused") {
361 isPaused = true; 362 isPaused = true;
362 } else { 363 } else {
363 error("unknown debugger event received"); 364 error("Error: unknown debugger event received");
364 } 365 }
365 } 366 }
366 367
367 // Handle one JSON message object and match it to the 368 // Handle one JSON message object and match it to the
368 // expected events and responses in the debugging script. 369 // expected events and responses in the debugging script.
369 void handleMessage(Map<String,dynamic> receivedMsg) { 370 void handleMessage(Map<String,dynamic> receivedMsg) {
370 currentMessage = receivedMsg; 371 currentMessage = receivedMsg;
371 if (receivedMsg["event"] != null) { 372 if (receivedMsg["event"] != null) {
372 handleEvent(receivedMsg); 373 handleEvent(receivedMsg);
373 if (errorsDetected) { 374 if (errorsDetected) {
(...skipping 28 matching lines...) Expand all
402 // Handle data received over the wire from the debug target 403 // Handle data received over the wire from the debug target
403 // process. Split input from JSON wire format into individual 404 // process. Split input from JSON wire format into individual
404 // message objects (maps). 405 // message objects (maps).
405 void handleMessages() { 406 void handleMessages() {
406 var msg = responses.getNextMessage(); 407 var msg = responses.getNextMessage();
407 while (msg != null) { 408 while (msg != null) {
408 if (verboseWire) print("RECV: $msg"); 409 if (verboseWire) print("RECV: $msg");
409 if (responses.haveGarbage()) { 410 if (responses.haveGarbage()) {
410 error("Error: leftover text after message: '${responses.buffer}'"); 411 error("Error: leftover text after message: '${responses.buffer}'");
411 error("Previous message may be malformed, was: '$msg'"); 412 error("Previous message may be malformed, was: '$msg'");
412 close(killDebugee: true); 413 cleanup();
413 return; 414 return;
414 } 415 }
415 var msgObj = JSON.parse(msg); 416 var msgObj = JSON.parse(msg);
416 handleMessage(msgObj); 417 handleMessage(msgObj);
417 if (errorsDetected) { 418 if (errorsDetected) {
418 error("Error while handling script entry"); 419 error("Error while handling script entry");
419 error("Message received from debug target: $msg"); 420 error("Message received from debug target: $msg");
420 close(killDebugee: true); 421 cleanup();
421 return; 422 return;
422 } 423 }
423 if (shutdownEventSeen) { 424 if (shutdownEventSeen) {
424 close(); 425 cleanup();
425 return; 426 return;
426 } 427 }
427 if (isPaused) sendNextCommand(); 428 if (isPaused) sendNextCommand();
428 msg = responses.getNextMessage(); 429 msg = responses.getNextMessage();
429 } 430 }
430 } 431 }
431 432
432 runScript(List entries) { 433 runScript(List entries) {
433 script = new DebugScript(entries); 434 script = new DebugScript(entries);
434 openConnection(); 435 openConnection();
(...skipping 22 matching lines...) Expand all
457 void openConnection() { 458 void openConnection() {
458 Socket.connect("127.0.0.1", portNumber).then((s) { 459 Socket.connect("127.0.0.1", portNumber).then((s) {
459 this.socket = s; 460 this.socket = s;
460 var stringStream = socket.transform(new StringDecoder()); 461 var stringStream = socket.transform(new StringDecoder());
461 stringStream.listen((str) { 462 stringStream.listen((str) {
462 try { 463 try {
463 responses.append(str); 464 responses.append(str);
464 handleMessages(); 465 handleMessages();
465 } catch(e, trace) { 466 } catch(e, trace) {
466 print("Unexpected exception:\n$e\n$trace"); 467 print("Unexpected exception:\n$e\n$trace");
467 close(killDebugee: true); 468 cleanup();
468 } 469 }
469 }, 470 },
470 onDone: () { 471 onDone: () {
471 print("Connection closed by debug target"); 472 print("Connection closed by debug target");
472 close(killDebugee: true); 473 cleanup();
473 }, 474 },
474 onError: (e) { 475 onError: (e) {
475 print("Error '$e' detected in input stream from debug target"); 476 print("Error '$e' detected in input stream from debug target");
476 var trace = getAttachedStackTrace(e); 477 var trace = getAttachedStackTrace(e);
477 if (trace != null) print("StackTrace: $trace"); 478 if (trace != null) print("StackTrace: $trace");
478 close(killDebugee: true); 479 cleanup();
479 }); 480 });
480 }, 481 },
481 onError: (e) { 482 onError: (e) {
482 String msg = "Error while connecting to debugee: $e"; 483 String msg = "Error while connecting to debugee: $e";
483 var trace = getAttachedStackTrace(e); 484 var trace = getAttachedStackTrace(e);
484 if (trace != null) msg += "\nStackTrace: $trace"; 485 if (trace != null) msg += "\nStackTrace: $trace";
485 error(msg); 486 error(msg);
486 close(killDebugee: true); 487 cleanup();
487 }); 488 });
488 } 489 }
489 490
490 void close({killDebugee: false}) { 491 void cleanup() {
491 void printErrorsAndExit() { 492 if (cleanupDone) return;
492 if (errorsDetected) throw "Errors detected";
493 exit(errors.length);
494 }
495 if (errorsDetected) {
496 for (int i = 0; i < errors.length; i++) print(errors[i]);
497 }
498 if (socket != null) { 493 if (socket != null) {
499 socket.close().catchError((error) { 494 socket.close().catchError((error) {
500 print("Error occured while closing socket: $error"); 495 // Print this directly in addition to adding it to the
496 // error message queue, in case the error message queue
497 // gets printed before this error handler is called.
498 print("Error occurred while closing socket: $error");
499 error("Error while closing socket: $error");
501 }); 500 });
502 } 501 }
503 if (killDebugee) { 502 targetProcess.kill();
504 if (!targetProcess.kill()) { 503 // If the process was already dead exitCode is already
505 print("Could not send kill signal to target process."); 504 // available and we call exit() in the next event loop cycle.
506 } else { 505 // Otherwise this will wait for the process to exit.
507 print("Successfully sent kill signal to target process."); 506 targetProcess.exitCode.then((exitCode) {
507 if (errorsDetected) {
508 print("\n===== Errors detected: =====");
509 for (int i = 0; i < errors.length; i++) print(errors[i]);
510 print("============================\n");
508 } 511 }
509 // If the process was already dead exitCode is already 512 exit(errors.length);
510 // available and we call exit() in the next event loop cycle. 513 });
511 // Otherwise this will wait for the process to exit. 514 cleanupDone = true;
512 targetProcess.exitCode.then((exitCode) {
513 printErrorsAndExit();
514 });
515 } else {
516 printErrorsAndExit();
517 }
518 } 515 }
519 } 516 }
520 517
521 518
522 bool RunScript(List script) { 519 bool RunScript(List script) {
523 var options = new Options(); 520 var options = new Options();
524 if (options.arguments.contains("--debuggee")) { 521 if (options.arguments.contains("--debuggee")) {
525 return false; 522 return false;
526 } 523 }
527 verboseWire = options.arguments.contains("--wire"); 524 verboseWire = options.arguments.contains("--wire");
(...skipping 30 matching lines...) Expand all
558 var trace = getAttachedStackTrace(e); 555 var trace = getAttachedStackTrace(e);
559 if (trace != null) print("StackTrace: $trace"); 556 if (trace != null) print("StackTrace: $trace");
560 return -1; 557 return -1;
561 } else { 558 } else {
562 // Retry with another random port. 559 // Retry with another random port.
563 RunScript(script); 560 RunScript(script);
564 } 561 }
565 }); 562 });
566 return true; 563 return true;
567 } 564 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698