| OLD | NEW |
| 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:io"; | 8 import "dart:io"; |
| 9 import "dart:json" as json; | 9 import "dart:json" as json; |
| 10 import "dart:utf"; | 10 import "dart:utf"; |
| 11 import "dart:async"; | 11 import "dart:async"; |
| 12 | 12 |
| 13 | 13 |
| 14 Map<int, Completer> outstandingCommands; | 14 Map<int, Completer> outstandingCommands; |
| 15 | 15 |
| 16 Socket vmSock; | 16 Socket vmSock; |
| 17 String vmData; | 17 String vmData; |
| 18 OutputStream vmStream; | 18 StreamSubscription<String> streamSubscription; |
| 19 int seqNum = 0; | 19 int seqNum = 0; |
| 20 int isolate_id = -1; | 20 int isolate_id = -1; |
| 21 | 21 |
| 22 bool verbose = false; | 22 bool verbose = false; |
| 23 | 23 |
| 24 // The current stack trace, while the VM is paused. It's a list | 24 // The current stack trace, while the VM is paused. It's a list |
| 25 // of activation frames. | 25 // of activation frames. |
| 26 List stackTrace; | 26 List stackTrace; |
| 27 | 27 |
| 28 // The current activation frame, while the VM is paused. | 28 // The current activation frame, while the VM is paused. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 49 ls <lib_id> List loaded scripts in library | 49 ls <lib_id> List loaded scripts in library |
| 50 gs <lib_id> <script_url> Get source text of script in library | 50 gs <lib_id> <script_url> Get source text of script in library |
| 51 epi <none|all|unhandled> Set exception pause info | 51 epi <none|all|unhandled> Set exception pause info |
| 52 i <id> Interrupt execution of given isolate id | 52 i <id> Interrupt execution of given isolate id |
| 53 h Print help | 53 h Print help |
| 54 """); | 54 """); |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 void quitShell() { | 58 void quitShell() { |
| 59 vmStream.close(); | 59 streamSubscription.cancel(); |
| 60 vmSock.close(); | 60 vmSock.close(); |
| 61 stdin.close(); | 61 stdin.close(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 Future sendCmd(Map<String, dynamic> cmd) { | 65 Future sendCmd(Map<String, dynamic> cmd) { |
| 66 var completer = new Completer(); | 66 var completer = new Completer(); |
| 67 int id = cmd["id"]; | 67 int id = cmd["id"]; |
| 68 outstandingCommands[id] = completer; | 68 outstandingCommands[id] = completer; |
| 69 if (verbose) { | 69 if (verbose) { |
| 70 print("sending: '${json.stringify(cmd)}'"); | 70 print("sending: '${json.stringify(cmd)}'"); |
| 71 } | 71 } |
| 72 vmStream.writeString(json.stringify(cmd)); | 72 vmSock.addString(json.stringify(cmd)); |
| 73 return completer.future; | 73 return completer.future; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 void processCommand(String cmdLine) { | 77 void processCommand(String cmdLine) { |
| 78 seqNum++; | 78 seqNum++; |
| 79 var args = cmdLine.split(' '); | 79 var args = cmdLine.split(' '); |
| 80 if (args.length == 0) { | 80 if (args.length == 0) { |
| 81 return; | 81 return; |
| 82 } | 82 } |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 // Strings can contain braces. Skip their content. | 521 // Strings can contain braces. Skip their content. |
| 522 index = skipString(index); | 522 index = skipString(index); |
| 523 } | 523 } |
| 524 } | 524 } |
| 525 return 0; | 525 return 0; |
| 526 } | 526 } |
| 527 | 527 |
| 528 | 528 |
| 529 void debuggerMain() { | 529 void debuggerMain() { |
| 530 outstandingCommands = new Map<int, Completer>(); | 530 outstandingCommands = new Map<int, Completer>(); |
| 531 vmSock = new Socket("127.0.0.1", 5858); | 531 Socket.connect("127.0.0.1", 5858).then((s) { |
| 532 vmStream = vmSock.outputStream; | 532 vmSock = s; |
| 533 var stdinStream = new StringInputStream(stdin); | 533 Stream<String> stringStream = vmSock.transform(new StringDecoder()); |
| 534 stdinStream.onLine = () { | 534 streamSubscription = stringStream.listen( |
| 535 processCommand(stdinStream.readLine()); | 535 (String data) { |
| 536 }; | 536 processVmData(data); |
| 537 var vmInStream = vmSock.inputStream; | 537 }, |
| 538 vmInStream.onData = () { | 538 onDone: () { |
| 539 String s = decodeUtf8(vmInStream.read()); | 539 print("VM debugger connection closed"); |
| 540 processVmData(s); | 540 quitShell(); |
| 541 }; | 541 }, |
| 542 vmInStream.onError = (err) { | 542 onError: (err) { |
| 543 print("Error in debug connection: $err"); | 543 print("Error in debug connection: $err"); |
| 544 quitShell(); | 544 quitShell(); |
| 545 }; | 545 }); |
| 546 vmInStream.onClosed = () { | 546 stdin.transform(new StringDecoder()) |
| 547 print("VM debugger connection closed"); | 547 .transform(new LineTransformer()) |
| 548 quitShell(); | 548 .listen((String line) => processCommand(line)); |
| 549 }; | 549 }); |
| 550 } | 550 } |
| 551 | 551 |
| 552 void main() { | 552 void main() { |
| 553 Options options = new Options(); | 553 Options options = new Options(); |
| 554 List<String> arguments = options.arguments; | 554 List<String> arguments = options.arguments; |
| 555 if (arguments.length > 0) { | 555 if (arguments.length > 0) { |
| 556 arguments = <String>['--debug', '--verbose_debug']..addAll(arguments); | 556 arguments = <String>['--debug', '--verbose_debug']..addAll(arguments); |
| 557 Process.start(options.executable, arguments).then((Process process) { | 557 Process.start(options.executable, arguments).then((Process process) { |
| 558 process.onExit = (int exitCode) { | 558 process.stdin.close(); |
| 559 process.exitCode.then((int exitCode) { |
| 559 print('${arguments.join(" ")} exited with $exitCode'); | 560 print('${arguments.join(" ")} exited with $exitCode'); |
| 560 }; | 561 }); |
| 561 process.stdin.close(); | |
| 562 // Redirecting both stdout and stderr of the child process to | |
| 563 // stdout. This should help users keep track of which errors | |
| 564 // are coming from the debugger, and which errors are coming | |
| 565 // from the process being debugged. | |
| 566 process.stderr.pipe(stdout); | |
| 567 process.stdout.pipe(stdout); | |
| 568 debuggerMain(); | 562 debuggerMain(); |
| 569 }); | 563 }); |
| 570 } else { | 564 } else { |
| 571 debuggerMain(); | 565 debuggerMain(); |
| 572 } | 566 } |
| 573 } | 567 } |
| OLD | NEW |