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:convert"; | 8 import "dart:convert"; |
9 import "dart:io"; | 9 import "dart:io"; |
10 import "dart:async"; | 10 import "dart:async"; |
(...skipping 29 matching lines...) Expand all Loading... |
40 Map<int, Completer> outstandingCommands; | 40 Map<int, Completer> outstandingCommands; |
41 | 41 |
42 Socket vmSock; | 42 Socket vmSock; |
43 String vmData; | 43 String vmData; |
44 var cmdSubscription; | 44 var cmdSubscription; |
45 Commando cmdo; | 45 Commando cmdo; |
46 var vmSubscription; | 46 var vmSubscription; |
47 int seqNum = 0; | 47 int seqNum = 0; |
48 | 48 |
49 bool isDebugging = false; | 49 bool isDebugging = false; |
50 bool stepMode = false; | |
51 Process targetProcess = null; | 50 Process targetProcess = null; |
52 bool suppressNextExitCode = false; | 51 bool suppressNextExitCode = false; |
53 | 52 |
54 final verbose = false; | 53 final verbose = false; |
55 final printMessages = false; | 54 final printMessages = false; |
56 | 55 |
57 TargetIsolate currentIsolate; | 56 TargetIsolate currentIsolate; |
58 TargetIsolate mainIsolate; | 57 TargetIsolate mainIsolate; |
59 | 58 |
60 int debugPort = 5858; | 59 int debugPort = 5858; |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 typedef void HandlerType(Map response); | 503 typedef void HandlerType(Map response); |
505 | 504 |
506 HandlerType showPromptAfter(void handler(Map response)) { | 505 HandlerType showPromptAfter(void handler(Map response)) { |
507 return (response) { | 506 return (response) { |
508 handler(response); | 507 handler(response); |
509 cmdo.show(); | 508 cmdo.show(); |
510 }; | 509 }; |
511 } | 510 } |
512 | 511 |
513 void processCommand(String cmdLine) { | 512 void processCommand(String cmdLine) { |
514 | |
515 void huh() { | 513 void huh() { |
516 print("'$cmdLine' not understood, try 'help' for help."); | 514 print("'$cmdLine' not understood, try 'help' for help."); |
517 } | 515 } |
518 | 516 |
519 cmdo.hide(); | 517 cmdo.hide(); |
520 seqNum++; | 518 seqNum++; |
521 cmdLine = cmdLine.trim(); | 519 cmdLine = cmdLine.trim(); |
522 var args = cmdLine.split(' '); | 520 var args = cmdLine.split(' '); |
523 if (args.length == 0) { | 521 if (args.length == 0) { |
524 return; | 522 return; |
525 } | 523 } |
526 var command = args[0]; | 524 var command = args[0]; |
527 | 525 |
528 var resume_commands = | 526 var resume_commands = |
529 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'}; | 527 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'}; |
530 if (resume_commands[command] != null) { | 528 if (resume_commands[command] != null) { |
531 if (!checkPaused()) return; | 529 if (!checkPaused()) return; |
532 // TODO(turnidge): step mode isn't quite right yet. | |
533 stepMode = (command != 'r'); | |
534 var cmd = { "id": seqNum, | 530 var cmd = { "id": seqNum, |
535 "command": resume_commands[command], | 531 "command": resume_commands[command], |
536 "params": { "isolateId" : currentIsolate.id } }; | 532 "params": { "isolateId" : currentIsolate.id } }; |
537 sendCmd(cmd).then(showPromptAfter(handleResumedResponse)); | 533 sendCmd(cmd).then(showPromptAfter(handleResumedResponse)); |
538 } else if (command == "bt") { | 534 } else if (command == "bt") { |
539 var cmd = { "id": seqNum, | 535 var cmd = { "id": seqNum, |
540 "command": "getStackTrace", | 536 "command": "getStackTrace", |
541 "params": { "isolateId" : currentIsolate.id } }; | 537 "params": { "isolateId" : currentIsolate.id } }; |
542 sendCmd(cmd).then(showPromptAfter(handleStackTraceResponse)); | 538 sendCmd(cmd).then(showPromptAfter(handleStackTraceResponse)); |
543 } else if (command == "ll") { | 539 } else if (command == "ll") { |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 var reason = msg["params"]["reason"]; | 1022 var reason = msg["params"]["reason"]; |
1027 int isolateId = msg["params"]["isolateId"]; | 1023 int isolateId = msg["params"]["isolateId"]; |
1028 assert(isolateId != null); | 1024 assert(isolateId != null); |
1029 var isolate = targetIsolates[isolateId]; | 1025 var isolate = targetIsolates[isolateId]; |
1030 assert(isolate != null); | 1026 assert(isolate != null); |
1031 assert(!isolate.isPaused); | 1027 assert(!isolate.isPaused); |
1032 var location = msg["params"]["location"];; | 1028 var location = msg["params"]["location"];; |
1033 assert(location != null); | 1029 assert(location != null); |
1034 isolate.pausedLocation = location; | 1030 isolate.pausedLocation = location; |
1035 if (reason == "breakpoint") { | 1031 if (reason == "breakpoint") { |
1036 return printLocation((stepMode ? null : "Breakpoint"), location); | 1032 var bpId = (msg["params"]["breakpointId"]); |
| 1033 var label = (bpId != null) ? "Breakpoint $bpId" : null; |
| 1034 return printLocation(label, location); |
1037 } else if (reason == "interrupted") { | 1035 } else if (reason == "interrupted") { |
1038 stepMode = false; | |
1039 return printLocation("Interrupted", location); | 1036 return printLocation("Interrupted", location); |
1040 } else { | 1037 } else { |
1041 assert(reason == "exception"); | 1038 assert(reason == "exception"); |
1042 var excObj = msg["params"]["exception"]; | 1039 var excObj = msg["params"]["exception"]; |
1043 print("Isolate $isolateId paused on exception"); | 1040 print("Isolate $isolateId paused on exception"); |
1044 print(remoteObject(excObj)); | 1041 print(remoteObject(excObj)); |
1045 return new Future.value(); | 1042 return new Future.value(); |
1046 } | 1043 } |
1047 } | 1044 } |
1048 | 1045 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 bool haveGarbageVmData() { | 1130 bool haveGarbageVmData() { |
1134 if (vmData == null || vmData.length == 0) return false; | 1131 if (vmData == null || vmData.length == 0) return false; |
1135 var i = 0, char = " "; | 1132 var i = 0, char = " "; |
1136 while (i < vmData.length) { | 1133 while (i < vmData.length) { |
1137 char = vmData[i]; | 1134 char = vmData[i]; |
1138 if (char != " " && char != "\n" && char != "\r" && char != "\t") break; | 1135 if (char != " " && char != "\n" && char != "\r" && char != "\t") break; |
1139 i++; | 1136 i++; |
1140 } | 1137 } |
1141 if (i >= vmData.length) { | 1138 if (i >= vmData.length) { |
1142 return false; | 1139 return false; |
1143 } else { | 1140 } else { |
1144 return char != "{"; | 1141 return char != "{"; |
1145 } | 1142 } |
1146 } | 1143 } |
1147 | 1144 |
1148 | 1145 |
1149 void processVmData(String data) { | 1146 void processVmData(String data) { |
1150 if (vmData == null || vmData.length == 0) { | 1147 if (vmData == null || vmData.length == 0) { |
1151 vmData = data; | 1148 vmData = data; |
1152 } else { | 1149 } else { |
1153 vmData = vmData + data; | 1150 vmData = vmData + data; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 delay = new Duration(milliseconds:10); | 1318 delay = new Duration(milliseconds:10); |
1322 } else if (attempt < 20) { | 1319 } else if (attempt < 20) { |
1323 delay = new Duration(seconds:1); | 1320 delay = new Duration(seconds:1); |
1324 } else { | 1321 } else { |
1325 // Too many retries. Give up. | 1322 // Too many retries. Give up. |
1326 // | 1323 // |
1327 // TODO(turnidge): Kill the debugged process here? | 1324 // TODO(turnidge): Kill the debugged process here? |
1328 print('Timed out waiting for debugger to start.\nError: $e'); | 1325 print('Timed out waiting for debugger to start.\nError: $e'); |
1329 return closeVmSocket(); | 1326 return closeVmSocket(); |
1330 } | 1327 } |
1331 | |
1332 // Wait and retry. | 1328 // Wait and retry. |
1333 return new Future.delayed(delay, () { | 1329 return new Future.delayed(delay, () { |
1334 openVmSocket(attempt + 1); | 1330 openVmSocket(attempt + 1); |
1335 }); | 1331 }); |
1336 } | 1332 } |
1337 | 1333 |
1338 | 1334 |
1339 Future closeVmSocket() { | 1335 Future closeVmSocket() { |
1340 if (vmSubscription == null) { | 1336 if (vmSubscription == null) { |
1341 // Already closed, nothing to do. | 1337 // Already closed, nothing to do. |
(...skipping 12 matching lines...) Expand all Loading... |
1354 // This is uglier than it needs to be since cancel can return null. | 1350 // This is uglier than it needs to be since cancel can return null. |
1355 var cleanupFutures = [sock.close()]; | 1351 var cleanupFutures = [sock.close()]; |
1356 var future = subscription.cancel(); | 1352 var future = subscription.cancel(); |
1357 if (future != null) { | 1353 if (future != null) { |
1358 cleanupFutures.add(future); | 1354 cleanupFutures.add(future); |
1359 } | 1355 } |
1360 | 1356 |
1361 vmSubscription = null; | 1357 vmSubscription = null; |
1362 vmSock = null; | 1358 vmSock = null; |
1363 outstandingCommands = null; | 1359 outstandingCommands = null; |
1364 | |
1365 return Future.wait(cleanupFutures); | 1360 return Future.wait(cleanupFutures); |
1366 } | 1361 } |
1367 | 1362 |
1368 void debuggerError(self, parent, zone, error, StackTrace trace) { | 1363 void debuggerError(self, parent, zone, error, StackTrace trace) { |
1369 print('\n--------\nExiting due to unexpected error:\n' | 1364 print('\n--------\nExiting due to unexpected error:\n' |
1370 ' $error\n$trace\n'); | 1365 ' $error\n$trace\n'); |
1371 debuggerQuit(); | 1366 debuggerQuit(); |
1372 } | 1367 } |
1373 | 1368 |
1374 Future debuggerQuit() { | 1369 Future debuggerQuit() { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 handleUncaughtError: debuggerError)); | 1404 handleUncaughtError: debuggerError)); |
1410 | 1405 |
1411 zone.run(() { | 1406 zone.run(() { |
1412 parseArgs(args); | 1407 parseArgs(args); |
1413 cmdo = new Commando(completer: debuggerCommandCompleter); | 1408 cmdo = new Commando(completer: debuggerCommandCompleter); |
1414 cmdSubscription = cmdo.commands.listen(processCommand, | 1409 cmdSubscription = cmdo.commands.listen(processCommand, |
1415 onError: processError, | 1410 onError: processError, |
1416 onDone: processDone); | 1411 onDone: processDone); |
1417 }); | 1412 }); |
1418 } | 1413 } |
OLD | NEW |