OLD | NEW |
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:io"; | 9 import "dart:io"; |
10 import "dart:math"; | 10 import "dart:math"; |
11 import "dart:utf"; | 11 import "dart:utf"; |
12 import "dart:json" as JSON; | 12 import "dart:json" as JSON; |
13 | 13 |
14 // Whether or not to print debug target process on the console. | |
15 var showDebuggeeOutput = true; | |
16 | |
17 // Whether or not to print the debugger wire messages on the console. | 14 // Whether or not to print the debugger wire messages on the console. |
18 var verboseWire = false; | 15 var verboseWire = false; |
19 | 16 |
20 // The number of attempts made to find an unused debugger port. | 17 // The number of attempts made to find an unused debugger port. |
21 var retries = 0; | 18 var retries = 0; |
22 | 19 |
23 // Class to buffer wire protocol data from debug target and | 20 // Class to buffer wire protocol data from debug target and |
24 // break it down to individual json messages. | 21 // break it down to individual json messages. |
25 class JsonBuffer { | 22 class JsonBuffer { |
26 String buffer = null; | 23 String buffer = null; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 Command lastCommand = null; // Most recent command sent to target. | 283 Command lastCommand = null; // Most recent command sent to target. |
287 List<String> errors = new List(); | 284 List<String> errors = new List(); |
288 | 285 |
289 // Data collected from debug target. | 286 // Data collected from debug target. |
290 Map currentMessage = null; // Currently handled message sent by target. | 287 Map currentMessage = null; // Currently handled message sent by target. |
291 String scriptUrl = null; | 288 String scriptUrl = null; |
292 bool shutdownEventSeen = false; | 289 bool shutdownEventSeen = false; |
293 int isolateId = 0; | 290 int isolateId = 0; |
294 bool isPaused = false; | 291 bool isPaused = false; |
295 | 292 |
296 Debugger(this.targetProcess, this.portNumber) { | 293 Debugger(this.targetProcess, this.portNumber, this.script) { |
297 stdin.listen((_) {}); | 294 stdin.listen((_) {}); |
298 var stdoutStringStream = targetProcess.stdout | 295 var stdoutStringStream = targetProcess.stdout |
299 .transform(new StringDecoder()) | 296 .transform(new StringDecoder()) |
300 .transform(new LineTransformer()); | 297 .transform(new LineTransformer()); |
301 stdoutStringStream.listen((line) { | 298 stdoutStringStream.listen((line) { |
302 if (showDebuggeeOutput) { | 299 if (line == "Debugger initialized") { |
303 print("TARG: $line"); | 300 openConnection(); |
304 } | 301 } |
| 302 print("TARG: $line"); |
305 }); | 303 }); |
306 | 304 |
307 var stderrStringStream = targetProcess.stderr | 305 var stderrStringStream = targetProcess.stderr |
308 .transform(new StringDecoder()) | 306 .transform(new StringDecoder()) |
309 .transform(new LineTransformer()); | 307 .transform(new LineTransformer()); |
310 stderrStringStream.listen((line) { | 308 stderrStringStream.listen((line) { |
311 if (showDebuggeeOutput) { | 309 print("TARG: $line"); |
312 print("TARG: $line"); | |
313 } | |
314 }); | 310 }); |
315 } | 311 } |
316 | 312 |
317 // Handle debugger events, updating the debugger state. | 313 // Handle debugger events, updating the debugger state. |
318 void handleEvent(Map<String,dynamic> msg) { | 314 void handleEvent(Map<String,dynamic> msg) { |
319 if (msg["event"] == "isolate") { | 315 if (msg["event"] == "isolate") { |
320 if (msg["params"]["reason"] == "created") { | 316 if (msg["params"]["reason"] == "created") { |
321 isolateId = msg["params"]["id"]; | 317 isolateId = msg["params"]["id"]; |
322 assert(isolateId != null); | 318 assert(isolateId != null); |
323 print("Debuggee isolate id $isolateId created."); | 319 print("Debuggee isolate id $isolateId created."); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 onDone: () { | 434 onDone: () { |
439 print("Connection closed by debug target"); | 435 print("Connection closed by debug target"); |
440 close(killDebugee: true); | 436 close(killDebugee: true); |
441 }, | 437 }, |
442 onError: (e) { | 438 onError: (e) { |
443 print("Error '$e' detected in input stream from debug target"); | 439 print("Error '$e' detected in input stream from debug target"); |
444 close(killDebugee: true); | 440 close(killDebugee: true); |
445 }); | 441 }); |
446 }, | 442 }, |
447 onError: (asyncErr) { | 443 onError: (asyncErr) { |
448 print("Error while connecting to debugee: $asyncErr"); | 444 error("Error while connecting to debugee: $asyncErr"); |
449 close(killDebugee: true); | 445 close(killDebugee: true); |
450 }); | 446 }); |
451 } | 447 } |
452 | 448 |
453 void close({killDebugee: false}) { | 449 void close({killDebugee: false}) { |
454 if (errorsDetected) { | 450 if (errorsDetected) { |
455 for (int i = 0; i < errors.length; i++) print(errors[i]); | 451 for (int i = 0; i < errors.length; i++) print(errors[i]); |
456 } | 452 } |
457 if (socket != null) socket.close(); | 453 if (socket != null) socket.close(); |
458 if (killDebugee) { | 454 if (killDebugee) { |
459 targetProcess.kill(); | 455 targetProcess.kill(); |
460 print("Target process killed"); | 456 print("Target process killed"); |
461 } | 457 } |
462 Expect.isTrue(!errorsDetected); | 458 Expect.isTrue(!errorsDetected); |
463 exit(errors.length); | 459 exit(errors.length); |
464 } | 460 } |
465 } | 461 } |
466 | 462 |
467 | 463 |
468 bool RunScript(List script) { | 464 bool RunScript(List script) { |
469 var options = new Options(); | 465 var options = new Options(); |
470 if (options.arguments.contains("--debuggee")) { | 466 if (options.arguments.contains("--debuggee")) { |
471 return false; | 467 return false; |
472 } | 468 } |
473 // The default is to show debugging output. | |
474 showDebuggeeOutput = !options.arguments.contains("--non-verbose"); | |
475 verboseWire = options.arguments.contains("--wire"); | 469 verboseWire = options.arguments.contains("--wire"); |
476 | 470 |
477 // Pick a port in the upper half of the port number range. | 471 // Pick a port in the upper half of the port number range. |
478 var seed = new DateTime.now().millisecondsSinceEpoch; | 472 var seed = new DateTime.now().millisecondsSinceEpoch; |
479 Random random = new Random(seed); | 473 Random random = new Random(seed); |
480 var debugPort = random.nextInt(32000) + 32000; | 474 var debugPort = random.nextInt(32000) + 32000; |
481 print('using debug port $debugPort ...'); | 475 print('using debug port $debugPort ...'); |
482 ServerSocket.bind('127.0.0.1', debugPort).then((ServerSocket s) { | 476 ServerSocket.bind('127.0.0.1', debugPort).then((ServerSocket s) { |
483 s.close(); | 477 s.close(); |
484 var targetOpts = [ "--debug:$debugPort" ]; | 478 var targetOpts = [ "--debug:$debugPort" ]; |
485 if (showDebuggeeOutput) targetOpts.add("--verbose_debug"); | 479 // --verbose_debug is necessary so the test knows when the debuggee |
| 480 // is initialized. |
| 481 targetOpts.add("--verbose_debug"); |
486 targetOpts.add(options.script); | 482 targetOpts.add(options.script); |
487 targetOpts.add("--debuggee"); | 483 targetOpts.add("--debuggee"); |
| 484 print('args: ${targetOpts.join(" ")}'); |
488 | 485 |
489 Process.start(options.executable, targetOpts).then((Process process) { | 486 Process.start(options.executable, targetOpts).then((Process process) { |
490 print("Debug target process started"); | 487 print("Debug target process started"); |
491 process.stdin.close(); | 488 process.stdin.close(); |
492 process.exitCode.then((int exitCode) { | 489 process.exitCode.then((int exitCode) { |
493 Expect.equals(0, exitCode); | 490 Expect.equals(0, exitCode); |
494 print("Debug target process exited with exit code $exitCode"); | 491 print("Debug target process exited with exit code $exitCode"); |
495 }); | 492 }); |
496 var debugger = new Debugger(process, debugPort); | 493 var debugger = |
497 debugger.runScript(script); | 494 new Debugger(process, debugPort, new DebugScript(script)); |
498 }); | 495 }); |
499 }, | 496 }, |
500 onError: (e) { | 497 onError: (e) { |
501 if (++retries >= 3) { | 498 if (++retries >= 3) { |
502 print('unable to find unused port: $e'); | 499 print('unable to find unused port: $e'); |
503 return -1; | 500 return -1; |
504 } else { | 501 } else { |
505 // Retry with another random port. | 502 // Retry with another random port. |
506 RunScript(script); | 503 RunScript(script); |
507 } | 504 } |
508 }); | 505 }); |
509 return true; | 506 return true; |
510 } | 507 } |
OLD | NEW |