Chromium Code Reviews| 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"; |
| 11 | 11 |
| 12 | 12 |
| 13 class TargetIsolate { | |
| 14 int id; | |
| 15 // The location of the last paused event. | |
| 16 Map pausedLocation = null; | |
| 17 | |
| 18 TargetIsolate(this.id); | |
| 19 bool get isPaused => pausedLocation != null; | |
| 20 } | |
| 21 | |
| 22 Map<int, TargetIsolate> targetIsolates= new Map<int, TargetIsolate>(); | |
| 13 Map<int, Completer> outstandingCommands; | 23 Map<int, Completer> outstandingCommands; |
| 14 | 24 |
| 15 Socket vmSock; | 25 Socket vmSock; |
| 16 String vmData; | 26 String vmData; |
| 17 var stdinSubscription; | 27 var stdinSubscription; |
| 18 var vmSubscription; | 28 var vmSubscription; |
| 19 int seqNum = 0; | 29 int seqNum = 0; |
| 20 int isolate_id = -1; | |
| 21 | 30 |
| 22 final verbose = false; | 31 final verbose = false; |
| 23 final printMessages = false; | 32 final printMessages = false; |
| 24 | 33 |
| 25 // The location of the last paused event. | 34 TargetIsolate currentIsolate; |
| 26 Map pausedLocation = null; | 35 TargetIsolate mainIsolate; |
| 27 | 36 |
| 28 | 37 |
| 29 void printHelp() { | 38 void printHelp() { |
| 30 print(""" | 39 print(""" |
| 31 q Quit debugger shell | 40 q Quit debugger shell |
| 32 bt Show backtrace | 41 bt Show backtrace |
| 33 r Resume execution | 42 r Resume execution |
| 34 s Single step | 43 s Single step |
| 35 so Step over | 44 so Step over |
| 36 si Step into | 45 si Step into |
| 37 sbp [<file>] <line> Set breakpoint | 46 sbp [<file>] <line> Set breakpoint |
| 38 rbp <id> Remove breakpoint with given id | 47 rbp <id> Remove breakpoint with given id |
| 39 po <id> Print object info for given id | 48 po <id> Print object info for given id |
| 40 eval obj <id> <expr> Evaluate expr on object id | 49 eval obj <id> <expr> Evaluate expr on object id |
| 41 eval cls <id> <expr> Evaluate expr on class id | 50 eval cls <id> <expr> Evaluate expr on class id |
| 42 eval lib <id> <expr> Evaluate expr in toplevel of library id | 51 eval lib <id> <expr> Evaluate expr in toplevel of library id |
| 43 pl <id> <idx> [<len>] Print list element/slice | 52 pl <id> <idx> [<len>] Print list element/slice |
| 44 pc <id> Print class info for given id | 53 pc <id> Print class info for given id |
| 45 ll List loaded libraries | 54 ll List loaded libraries |
| 46 plib <id> Print library info for given library id | 55 plib <id> Print library info for given library id |
| 47 slib <id> <true|false> Set library id debuggable | 56 slib <id> <true|false> Set library id debuggable |
| 48 pg <id> Print all global variables visible within given library id | 57 pg <id> Print all global variables visible within given library id |
| 49 ls <lib_id> List loaded scripts in library | 58 ls <lib_id> List loaded scripts in library |
| 50 gs <lib_id> <script_url> Get source text of script in library | 59 gs <lib_id> <script_url> Get source text of script in library |
| 51 tok <lib_id> <script_url> Get line and token table of script in library | 60 tok <lib_id> <script_url> Get line and token table of script in library |
| 52 epi <none|all|unhandled> Set exception pause info | 61 epi <none|all|unhandled> Set exception pause info |
| 53 li List ids of all isolates in the VM | 62 li List ids of all isolates in the VM |
| 63 sci <id> Set current target isolate | |
| 54 i <id> Interrupt execution of given isolate id | 64 i <id> Interrupt execution of given isolate id |
| 55 h Print help | 65 h Print help |
| 56 """); | 66 """); |
| 57 } | 67 } |
| 58 | 68 |
| 59 | 69 |
| 70 String formatLocation(Map location) { | |
| 71 if (location == null) return ""; | |
| 72 var fileName = location["url"].split("/").last; | |
| 73 return "file: $fileName lib: ${location['libraryId']} token: ${location['token Offset']}"; | |
| 74 } | |
| 75 | |
| 76 | |
| 60 void quitShell() { | 77 void quitShell() { |
| 61 vmSubscription.cancel(); | 78 vmSubscription.cancel(); |
| 62 vmSock.close(); | 79 vmSock.close(); |
| 63 stdinSubscription.cancel(); | 80 stdinSubscription.cancel(); |
| 64 } | 81 } |
| 65 | 82 |
| 66 | 83 |
| 67 Future sendCmd(Map<String, dynamic> cmd) { | 84 Future sendCmd(Map<String, dynamic> cmd) { |
| 68 var completer = new Completer(); | 85 var completer = new Completer(); |
| 69 int id = cmd["id"]; | 86 int id = cmd["id"]; |
| 70 outstandingCommands[id] = completer; | 87 outstandingCommands[id] = completer; |
| 71 if (verbose) { | 88 if (verbose) { |
| 72 print("sending: '${JSON.encode(cmd)}'"); | 89 print("sending: '${JSON.encode(cmd)}'"); |
| 73 } | 90 } |
| 74 vmSock.write(JSON.encode(cmd)); | 91 vmSock.write(JSON.encode(cmd)); |
| 75 return completer.future; | 92 return completer.future; |
| 76 } | 93 } |
| 77 | 94 |
| 95 bool checkCurrentIsolate() { | |
| 96 if (currentIsolate != null) { | |
| 97 return true; | |
| 98 } | |
| 99 print("Need valid current isolate"); | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 bool checkPaused() { | |
| 104 if (!checkCurrentIsolate()) return false; | |
| 105 if (currentIsolate.isPaused) return true; | |
| 106 print("Current isolate must be paused"); | |
| 107 return false; | |
| 108 } | |
| 109 | |
| 78 void processCommand(String cmdLine) { | 110 void processCommand(String cmdLine) { |
| 79 | 111 |
| 80 void huh() { | 112 void huh() { |
| 81 print("'$cmdLine' not understood, try h for help"); | 113 print("'$cmdLine' not understood, try h for help"); |
| 82 } | 114 } |
| 83 | 115 |
| 84 seqNum++; | 116 seqNum++; |
| 85 var args = cmdLine.split(' '); | 117 var args = cmdLine.split(' '); |
| 86 if (args.length == 0) { | 118 if (args.length == 0) { |
| 87 return; | 119 return; |
| 88 } | 120 } |
| 89 var command = args[0]; | 121 var command = args[0]; |
| 90 var simple_commands = | 122 var resume_commands = |
| 91 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'}; | 123 { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'}; |
| 92 if (simple_commands[command] != null) { | 124 if (resume_commands[command] != null) { |
| 125 if (!checkPaused()) return; | |
| 93 var cmd = { "id": seqNum, | 126 var cmd = { "id": seqNum, |
| 94 "command": simple_commands[command], | 127 "command": resume_commands[command], |
| 95 "params": { "isolateId" : isolate_id } }; | 128 "params": { "isolateId" : currentIsolate.id } }; |
| 96 sendCmd(cmd).then((result) => handleGenericResponse(result)); | 129 sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| 130 currentIsolate.pausedLocation = null; | |
|
turnidge
2013/11/22 19:24:00
I know that the sendCmd cannot complete immediatel
hausner
2013/11/22 22:54:42
Good point. Created a new handler that sets the pa
| |
| 97 } else if (command == "bt") { | 131 } else if (command == "bt") { |
| 98 var cmd = { "id": seqNum, | 132 var cmd = { "id": seqNum, |
| 99 "command": "getStackTrace", | 133 "command": "getStackTrace", |
| 100 "params": { "isolateId" : isolate_id } }; | 134 "params": { "isolateId" : currentIsolate.id } }; |
| 101 sendCmd(cmd).then((result) => handleStackTraceResponse(result)); | 135 sendCmd(cmd).then((result) => handleStackTraceResponse(result)); |
| 102 } else if (command == "ll") { | 136 } else if (command == "ll") { |
| 103 var cmd = { "id": seqNum, | 137 var cmd = { "id": seqNum, |
| 104 "command": "getLibraries", | 138 "command": "getLibraries", |
| 105 "params": { "isolateId" : isolate_id } }; | 139 "params": { "isolateId" : currentIsolate.id } }; |
| 106 sendCmd(cmd).then((result) => handleGetLibraryResponse(result)); | 140 sendCmd(cmd).then((result) => handleGetLibraryResponse(result)); |
| 107 } else if (command == "sbp" && args.length >= 2) { | 141 } else if (command == "sbp" && args.length >= 2) { |
| 108 var url, line; | 142 var url, line; |
| 109 if (args.length == 2 && pausedLocation != null) { | 143 if (args.length == 2 && currentIsolate.pausedLocation != null) { |
| 110 url = pausedLocation["url"]; | 144 url = currentIsolate.pausedLocation["url"]; |
| 111 assert(url != null); | 145 assert(url != null); |
| 112 line = int.parse(args[1]); | 146 line = int.parse(args[1]); |
| 113 } else { | 147 } else { |
| 114 url = args[1]; | 148 url = args[1]; |
| 115 line = int.parse(args[2]); | 149 line = int.parse(args[2]); |
| 116 } | 150 } |
| 117 var cmd = { "id": seqNum, | 151 var cmd = { "id": seqNum, |
| 118 "command": "setBreakpoint", | 152 "command": "setBreakpoint", |
| 119 "params": { "isolateId" : isolate_id, | 153 "params": { "isolateId" : currentIsolate.id, |
| 120 "url": url, | 154 "url": url, |
| 121 "line": line }}; | 155 "line": line }}; |
| 122 sendCmd(cmd).then((result) => handleSetBpResponse(result)); | 156 sendCmd(cmd).then((result) => handleSetBpResponse(result)); |
| 123 } else if (command == "rbp" && args.length == 2) { | 157 } else if (command == "rbp" && args.length == 2) { |
| 124 var cmd = { "id": seqNum, | 158 var cmd = { "id": seqNum, |
| 125 "command": "removeBreakpoint", | 159 "command": "removeBreakpoint", |
| 126 "params": { "isolateId" : isolate_id, | 160 "params": { "isolateId" : currentIsolate.id, |
| 127 "breakpointId": int.parse(args[1]) } }; | 161 "breakpointId": int.parse(args[1]) } }; |
| 128 sendCmd(cmd).then((result) => handleGenericResponse(result)); | 162 sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| 129 } else if (command == "ls" && args.length == 2) { | 163 } else if (command == "ls" && args.length == 2) { |
| 130 var cmd = { "id": seqNum, | 164 var cmd = { "id": seqNum, |
| 131 "command": "getScriptURLs", | 165 "command": "getScriptURLs", |
| 132 "params": { "isolateId" : isolate_id, | 166 "params": { "isolateId" : currentIsolate.id, |
| 133 "libraryId": int.parse(args[1]) } }; | 167 "libraryId": int.parse(args[1]) } }; |
| 134 sendCmd(cmd).then((result) => handleGetScriptsResponse(result)); | 168 sendCmd(cmd).then((result) => handleGetScriptsResponse(result)); |
| 135 } else if (command == "eval" && args.length > 3) { | 169 } else if (command == "eval" && args.length > 3) { |
| 136 var expr = args.getRange(3, args.length).join(" "); | 170 var expr = args.getRange(3, args.length).join(" "); |
| 137 var target = args[1]; | 171 var target = args[1]; |
| 138 if (target == "obj") { | 172 if (target == "obj") { |
| 139 target = "objectId"; | 173 target = "objectId"; |
| 140 } else if (target == "cls") { | 174 } else if (target == "cls") { |
| 141 target = "classId"; | 175 target = "classId"; |
| 142 } else if (target == "lib") { | 176 } else if (target == "lib") { |
| 143 target = "libraryId"; | 177 target = "libraryId"; |
| 144 } else { | 178 } else { |
| 145 huh(); | 179 huh(); |
| 146 return; | 180 return; |
| 147 } | 181 } |
| 148 var cmd = { "id": seqNum, | 182 var cmd = { "id": seqNum, |
| 149 "command": "evaluateExpr", | 183 "command": "evaluateExpr", |
| 150 "params": { "isolateId": isolate_id, | 184 "params": { "isolateId": currentIsolate.id, |
| 151 target: int.parse(args[2]), | 185 target: int.parse(args[2]), |
| 152 "expression": expr } }; | 186 "expression": expr } }; |
| 153 sendCmd(cmd).then((result) => handleEvalResponse(result)); | 187 sendCmd(cmd).then((result) => handleEvalResponse(result)); |
| 154 } else if (command == "po" && args.length == 2) { | 188 } else if (command == "po" && args.length == 2) { |
| 155 var cmd = { "id": seqNum, | 189 var cmd = { "id": seqNum, |
| 156 "command": "getObjectProperties", | 190 "command": "getObjectProperties", |
| 157 "params": { "isolateId" : isolate_id, | 191 "params": { "isolateId" : currentIsolate.id, |
| 158 "objectId": int.parse(args[1]) } }; | 192 "objectId": int.parse(args[1]) } }; |
| 159 sendCmd(cmd).then((result) => handleGetObjPropsResponse(result)); | 193 sendCmd(cmd).then((result) => handleGetObjPropsResponse(result)); |
| 160 } else if (command == "pl" && args.length >= 3) { | 194 } else if (command == "pl" && args.length >= 3) { |
| 161 var cmd; | 195 var cmd; |
| 162 if (args.length == 3) { | 196 if (args.length == 3) { |
| 163 cmd = { "id": seqNum, | 197 cmd = { "id": seqNum, |
| 164 "command": "getListElements", | 198 "command": "getListElements", |
| 165 "params": { "isolateId" : isolate_id, | 199 "params": { "isolateId" : currentIsolate.id, |
| 166 "objectId": int.parse(args[1]), | 200 "objectId": int.parse(args[1]), |
| 167 "index": int.parse(args[2]) } }; | 201 "index": int.parse(args[2]) } }; |
| 168 } else { | 202 } else { |
| 169 cmd = { "id": seqNum, | 203 cmd = { "id": seqNum, |
| 170 "command": "getListElements", | 204 "command": "getListElements", |
| 171 "params": { "isolateId" : isolate_id, | 205 "params": { "isolateId" : currentIsolate.id, |
| 172 "objectId": int.parse(args[1]), | 206 "objectId": int.parse(args[1]), |
| 173 "index": int.parse(args[2]), | 207 "index": int.parse(args[2]), |
| 174 "length": int.parse(args[3]) } }; | 208 "length": int.parse(args[3]) } }; |
| 175 } | 209 } |
| 176 sendCmd(cmd).then((result) => handleGetListResponse(result)); | 210 sendCmd(cmd).then((result) => handleGetListResponse(result)); |
| 177 } else if (command == "pc" && args.length == 2) { | 211 } else if (command == "pc" && args.length == 2) { |
| 178 var cmd = { "id": seqNum, | 212 var cmd = { "id": seqNum, |
| 179 "command": "getClassProperties", | 213 "command": "getClassProperties", |
| 180 "params": { "isolateId" : isolate_id, | 214 "params": { "isolateId" : currentIsolate.id, |
| 181 "classId": int.parse(args[1]) } }; | 215 "classId": int.parse(args[1]) } }; |
| 182 sendCmd(cmd).then((result) => handleGetClassPropsResponse(result)); | 216 sendCmd(cmd).then((result) => handleGetClassPropsResponse(result)); |
| 183 } else if (command == "plib" && args.length == 2) { | 217 } else if (command == "plib" && args.length == 2) { |
| 184 var cmd = { "id": seqNum, | 218 var cmd = { "id": seqNum, |
| 185 "command": "getLibraryProperties", | 219 "command": "getLibraryProperties", |
| 186 "params": {"isolateId" : isolate_id, | 220 "params": {"isolateId" : currentIsolate.id, |
| 187 "libraryId": int.parse(args[1]) } }; | 221 "libraryId": int.parse(args[1]) } }; |
| 188 sendCmd(cmd).then((result) => handleGetLibraryPropsResponse(result)); | 222 sendCmd(cmd).then((result) => handleGetLibraryPropsResponse(result)); |
| 189 } else if (command == "slib" && args.length == 3) { | 223 } else if (command == "slib" && args.length == 3) { |
| 190 var cmd = { "id": seqNum, | 224 var cmd = { "id": seqNum, |
| 191 "command": "setLibraryProperties", | 225 "command": "setLibraryProperties", |
| 192 "params": {"isolateId" : isolate_id, | 226 "params": {"isolateId" : currentIsolate.id, |
| 193 "libraryId": int.parse(args[1]), | 227 "libraryId": int.parse(args[1]), |
| 194 "debuggingEnabled": args[2] } }; | 228 "debuggingEnabled": args[2] } }; |
| 195 sendCmd(cmd).then((result) => handleSetLibraryPropsResponse(result)); | 229 sendCmd(cmd).then((result) => handleSetLibraryPropsResponse(result)); |
| 196 } else if (command == "pg" && args.length == 2) { | 230 } else if (command == "pg" && args.length == 2) { |
| 197 var cmd = { "id": seqNum, | 231 var cmd = { "id": seqNum, |
| 198 "command": "getGlobalVariables", | 232 "command": "getGlobalVariables", |
| 199 "params": { "isolateId" : isolate_id, | 233 "params": { "isolateId" : currentIsolate.id, |
| 200 "libraryId": int.parse(args[1]) } }; | 234 "libraryId": int.parse(args[1]) } }; |
| 201 sendCmd(cmd).then((result) => handleGetGlobalVarsResponse(result)); | 235 sendCmd(cmd).then((result) => handleGetGlobalVarsResponse(result)); |
| 202 } else if (command == "gs" && args.length == 3) { | 236 } else if (command == "gs" && args.length == 3) { |
| 203 var cmd = { "id": seqNum, | 237 var cmd = { "id": seqNum, |
| 204 "command": "getScriptSource", | 238 "command": "getScriptSource", |
| 205 "params": { "isolateId" : isolate_id, | 239 "params": { "isolateId" : currentIsolate.id, |
| 206 "libraryId": int.parse(args[1]), | 240 "libraryId": int.parse(args[1]), |
| 207 "url": args[2] } }; | 241 "url": args[2] } }; |
| 208 sendCmd(cmd).then((result) => handleGetSourceResponse(result)); | 242 sendCmd(cmd).then((result) => handleGetSourceResponse(result)); |
| 209 } else if (command == "tok" && args.length == 3) { | 243 } else if (command == "tok" && args.length == 3) { |
| 210 var cmd = { "id": seqNum, | 244 var cmd = { "id": seqNum, |
| 211 "command": "getLineNumberTable", | 245 "command": "getLineNumberTable", |
| 212 "params": { "isolateId" : isolate_id, | 246 "params": { "isolateId" : currentIsolate.id, |
| 213 "libraryId": int.parse(args[1]), | 247 "libraryId": int.parse(args[1]), |
| 214 "url": args[2] } }; | 248 "url": args[2] } }; |
| 215 sendCmd(cmd).then((result) => handleGetLineTableResponse(result)); | 249 sendCmd(cmd).then((result) => handleGetLineTableResponse(result)); |
| 216 } else if (command == "epi" && args.length == 2) { | 250 } else if (command == "epi" && args.length == 2) { |
| 217 var cmd = { "id": seqNum, | 251 var cmd = { "id": seqNum, |
| 218 "command": "setPauseOnException", | 252 "command": "setPauseOnException", |
| 219 "params": { "isolateId" : isolate_id, | 253 "params": { "isolateId" : currentIsolate.id, |
| 220 "exceptions": args[1] } }; | 254 "exceptions": args[1] } }; |
| 221 sendCmd(cmd).then((result) => handleGenericResponse(result)); | 255 sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| 222 } else if (command == "li") { | 256 } else if (command == "li") { |
| 223 var cmd = { "id": seqNum, "command": "getIsolateIds" }; | 257 var cmd = { "id": seqNum, "command": "getIsolateIds" }; |
| 224 sendCmd(cmd).then((result) => handleGetIsolatesResponse(result)); | 258 sendCmd(cmd).then((result) => handleGetIsolatesResponse(result)); |
| 259 } else if (command == "sci" && args.length == 2) { | |
| 260 var id = int.parse(args[1]); | |
| 261 if (targetIsolates[id] != null) { | |
| 262 currentIsolate = targetIsolates[id]; | |
| 263 print("Setting current target isolate to $id"); | |
| 264 } else { | |
| 265 print("$id is not a valid isolate id"); | |
| 266 } | |
| 225 } else if (command == "i" && args.length == 2) { | 267 } else if (command == "i" && args.length == 2) { |
| 226 var cmd = { "id": seqNum, | 268 var cmd = { "id": seqNum, |
| 227 "command": "interrupt", | 269 "command": "interrupt", |
| 228 "params": { "isolateId": int.parse(args[1]) } }; | 270 "params": { "isolateId": int.parse(args[1]) } }; |
| 229 sendCmd(cmd).then((result) => handleGenericResponse(result)); | 271 sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| 230 } else if (command == "q") { | 272 } else if (command == "q") { |
| 231 quitShell(); | 273 quitShell(); |
| 232 } else if (command == "h") { | 274 } else if (command == "h") { |
| 233 printHelp(); | 275 printHelp(); |
| 234 } else { | 276 } else { |
| 235 huh(); | 277 huh(); |
| 236 } | 278 } |
| 237 } | 279 } |
| 238 | 280 |
| 239 | 281 |
| 240 String remoteObject(value) { | 282 String remoteObject(value) { |
| 241 var kind = value["kind"]; | 283 var kind = value["kind"]; |
| 242 var text = value["text"]; | 284 var text = value["text"]; |
| 243 var id = value["objectId"]; | 285 var id = value["objectId"]; |
| 244 if (kind == "string") { | 286 if (kind == "string") { |
| 245 return "(string, id $id) '$text'"; | 287 return "(string, id $id) '$text'"; |
| 246 } else if (kind == "list") { | 288 } else if (kind == "list") { |
| 247 var len = value["length"]; | 289 var len = value["length"]; |
| 248 return "(list, id $id, len $len) $text"; | 290 return "(list, id $id, len $len) $text"; |
| 249 } else if (kind == "object") { | 291 } else if (kind == "object") { |
| 250 return "(obj, id $id) $text"; | 292 return "(obj, id $id) $text"; |
| 251 } else if (kind == "function") { | 293 } else if (kind == "function") { |
| 252 var location = value['location'] != null | 294 var location = formatLocation(value['location']); |
| 253 ? ", file '${value['location']['url']}'" | |
| 254 ", token pos ${value['location']['tokenOffset']}" | |
| 255 : ""; | |
| 256 var name = value['name']; | 295 var name = value['name']; |
| 257 var signature = value['signature']; | 296 var signature = value['signature']; |
| 258 return "(closure ${name}${signature} $location)"; | 297 return "(closure ${name}${signature} $location)"; |
| 259 } else { | 298 } else { |
| 260 return "$text"; | 299 return "$text"; |
| 261 } | 300 } |
| 262 } | 301 } |
| 263 | 302 |
| 264 | 303 |
| 265 printNamedObject(obj) { | 304 printNamedObject(obj) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 | 408 |
| 370 handleGetLineTableResponse(response) { | 409 handleGetLineTableResponse(response) { |
| 371 Map result = response["result"]; | 410 Map result = response["result"]; |
| 372 var info = result["lines"]; | 411 var info = result["lines"]; |
| 373 print("Line info table:\n$info"); | 412 print("Line info table:\n$info"); |
| 374 } | 413 } |
| 375 | 414 |
| 376 | 415 |
| 377 handleGetIsolatesResponse(response) { | 416 handleGetIsolatesResponse(response) { |
| 378 Map result = response["result"]; | 417 Map result = response["result"]; |
| 379 print("Isolates: ${result["isolateIds"]}"); | 418 List ids = result["isolateIds"]; |
| 419 assert(ids != null); | |
| 420 print("List of isolates:"); | |
| 421 for (int id in ids) { | |
| 422 TargetIsolate isolate = targetIsolates[id]; | |
| 423 var state = (isolate != null) ? "running" : "<unknown isolate>"; | |
| 424 if (isolate != null && isolate.isPaused) { | |
| 425 var loc = formatLocation(isolate.pausedLocation); | |
| 426 state = "paused at $loc"; | |
| 427 } | |
| 428 var marker = " "; | |
| 429 if (currentIsolate != null && id == currentIsolate.id) { | |
| 430 marker = "*"; | |
| 431 } | |
| 432 print("$marker $id $state"); | |
| 433 } | |
| 380 } | 434 } |
| 381 | 435 |
| 382 | 436 |
| 383 void handleGetLibraryResponse(response) { | 437 void handleGetLibraryResponse(response) { |
| 384 Map result = response["result"]; | 438 Map result = response["result"]; |
| 385 List libs = result["libraries"]; | 439 List libs = result["libraries"]; |
| 386 print("Loaded libraries:"); | 440 print("Loaded libraries:"); |
| 387 print(libs); | 441 print(libs); |
| 388 for (int i = 0; i < libs.length; i++) { | 442 for (int i = 0; i < libs.length; i++) { |
| 389 print(" ${libs[i]["id"]} ${libs[i]["url"]}"); | 443 print(" ${libs[i]["id"]} ${libs[i]["url"]}"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 void handleStackTraceResponse(response) { | 479 void handleStackTraceResponse(response) { |
| 426 Map result = response["result"]; | 480 Map result = response["result"]; |
| 427 List callFrames = result["callFrames"]; | 481 List callFrames = result["callFrames"]; |
| 428 assert(callFrames != null); | 482 assert(callFrames != null); |
| 429 printStackTrace(callFrames); | 483 printStackTrace(callFrames); |
| 430 } | 484 } |
| 431 | 485 |
| 432 | 486 |
| 433 void printStackFrame(frame_num, Map frame) { | 487 void printStackFrame(frame_num, Map frame) { |
| 434 var fname = frame["functionName"]; | 488 var fname = frame["functionName"]; |
| 435 var libId = frame["location"]["libraryId"]; | 489 var loc = formatLocation(frame["location"]); |
| 436 var url = frame["location"]["url"]; | 490 print("$frame_num $fname ($loc)"); |
| 437 var toff = frame["location"]["tokenOffset"]; | |
| 438 print("$frame_num $fname (url: $url token: $toff lib: $libId)"); | |
| 439 List locals = frame["locals"]; | 491 List locals = frame["locals"]; |
| 440 for (int i = 0; i < locals.length; i++) { | 492 for (int i = 0; i < locals.length; i++) { |
| 441 printNamedObject(locals[i]); | 493 printNamedObject(locals[i]); |
| 442 } | 494 } |
| 443 } | 495 } |
| 444 | 496 |
| 445 | 497 |
| 446 void printStackTrace(List frames) { | 498 void printStackTrace(List frames) { |
| 447 for (int i = 0; i < frames.length; i++) { | 499 for (int i = 0; i < frames.length; i++) { |
| 448 printStackFrame(i, frames[i]); | 500 printStackFrame(i, frames[i]); |
| 449 } | 501 } |
| 450 } | 502 } |
| 451 | 503 |
| 452 | 504 |
| 453 void handlePausedEvent(msg) { | 505 void handlePausedEvent(msg) { |
| 454 assert(msg["params"] != null); | 506 assert(msg["params"] != null); |
| 455 var reason = msg["params"]["reason"]; | 507 var reason = msg["params"]["reason"]; |
| 456 isolate_id = msg["params"]["isolateId"]; | 508 int isolateId = msg["params"]["isolateId"]; |
| 457 assert(isolate_id != null); | 509 assert(isolateId != null); |
| 458 pausedLocation = msg["params"]["location"]; | 510 var isolate = targetIsolates[isolateId]; |
| 459 assert(pausedLocation != null); | 511 assert(isolate != null); |
| 512 assert(!isolate.isPaused); | |
| 513 var location = msg["params"]["location"];; | |
| 514 assert(location != null); | |
| 515 isolate.pausedLocation = location; | |
| 460 if (reason == "breakpoint") { | 516 if (reason == "breakpoint") { |
| 461 print("Isolate $isolate_id paused on breakpoint"); | 517 print("Isolate $isolateId paused on breakpoint"); |
| 462 print("location: $pausedLocation"); | 518 print("location: ${formatLocation(location)}"); |
| 463 } else if (reason == "interrupted") { | 519 } else if (reason == "interrupted") { |
| 464 print("Isolate $isolate_id paused due to an interrupt"); | 520 print("Isolate $isolateId paused due to an interrupt"); |
| 521 print("location: ${formatLocation(location)}"); | |
| 465 } else { | 522 } else { |
| 466 assert(reason == "exception"); | 523 assert(reason == "exception"); |
| 467 var excObj = msg["params"]["exception"]; | 524 var excObj = msg["params"]["exception"]; |
| 468 print("Isolate $isolate_id paused on exception"); | 525 print("Isolate $isolateId paused on exception"); |
| 469 print(remoteObject(excObj)); | 526 print(remoteObject(excObj)); |
| 470 } | 527 } |
| 471 } | 528 } |
| 472 | 529 |
| 530 void handleIsolateEvent(msg) { | |
| 531 Map params = msg["params"]; | |
| 532 assert(params != null); | |
| 533 var isolateId = params["id"]; | |
| 534 var reason = params["reason"]; | |
| 535 if (reason == "created") { | |
| 536 print("Isolate $isolateId has been created."); | |
| 537 assert(targetIsolates[isolateId] == null); | |
| 538 targetIsolates[isolateId] = new TargetIsolate(isolateId); | |
| 539 if (mainIsolate == null) { | |
| 540 mainIsolate = targetIsolates[isolateId]; | |
| 541 currentIsolate = mainIsolate; | |
| 542 print("Current isolate set to ${currentIsolate.id}."); | |
| 543 } | |
| 544 } else { | |
| 545 assert(reason == "shutdown"); | |
| 546 var isolate = targetIsolates.remove(isolateId); | |
| 547 assert(isolate != null); | |
| 548 if (isolate == currentIsolate) { | |
| 549 currentIsolate == mainIsolate; | |
| 550 } | |
| 551 if (isolate == mainIsolate) { | |
| 552 mainIsolate = currentIsolate = null; | |
|
turnidge
2013/11/22 19:24:00
So terminating the main isolate always sets curren
hausner
2013/11/22 22:54:42
Probably not. The main isolate can terminate and t
| |
| 553 print("Main isolate has terminated."); | |
| 554 } else { | |
| 555 print("Isolate ${isolate.id} has terminated."); | |
| 556 } | |
| 557 if (currentIsolate != null) { | |
| 558 print("Setting current isolate to ${currentIsolate.id}."); | |
| 559 } | |
| 560 } | |
| 561 } | |
| 473 | 562 |
| 474 void processVmMessage(String jsonString) { | 563 void processVmMessage(String jsonString) { |
| 475 var msg = JSON.decode(jsonString); | 564 var msg = JSON.decode(jsonString); |
| 476 if (msg == null) { | 565 if (msg == null) { |
| 477 return; | 566 return; |
| 478 } | 567 } |
| 479 var event = msg["event"]; | 568 var event = msg["event"]; |
| 569 if (event == "isolate") { | |
| 570 handleIsolateEvent(msg); | |
| 571 return; | |
| 572 } | |
| 480 if (event == "paused") { | 573 if (event == "paused") { |
| 481 handlePausedEvent(msg); | 574 handlePausedEvent(msg); |
| 482 return; | 575 return; |
| 483 } | 576 } |
| 484 if (event == "breakpointResolved") { | 577 if (event == "breakpointResolved") { |
| 485 Map params = msg["params"]; | 578 Map params = msg["params"]; |
| 486 assert(params != null); | 579 assert(params != null); |
| 487 print("BP ${params["breakpointId"]} resolved and " | 580 var isolateId = params["isolateId"]; |
| 488 "set at line ${params["line"]}."); | 581 var location = formatLocation(params["location"]); |
| 489 return; | 582 print("BP ${params["breakpointId"]} resolved in isolate $isolateId" |
| 490 } | 583 " at $location."); |
| 491 if (event == "isolate") { | |
| 492 Map params = msg["params"]; | |
| 493 assert(params != null); | |
| 494 print("Isolate ${params["id"]} has been ${params["reason"]}."); | |
| 495 return; | 584 return; |
| 496 } | 585 } |
| 497 if (msg["id"] != null) { | 586 if (msg["id"] != null) { |
| 498 var id = msg["id"]; | 587 var id = msg["id"]; |
| 499 if (outstandingCommands.containsKey(id)) { | 588 if (outstandingCommands.containsKey(id)) { |
| 500 if (msg["error"] != null) { | 589 if (msg["error"] != null) { |
| 501 print("VM says: ${msg["error"]}"); | 590 print("VM says: ${msg["error"]}"); |
| 502 } else { | 591 } else { |
| 503 var completer = outstandingCommands[id]; | 592 var completer = outstandingCommands[id]; |
| 504 completer.complete(msg); | 593 completer.complete(msg); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 process.stdin.close(); | 730 process.stdin.close(); |
| 642 process.exitCode.then((int exitCode) { | 731 process.exitCode.then((int exitCode) { |
| 643 print('${arguments.join(" ")} exited with $exitCode'); | 732 print('${arguments.join(" ")} exited with $exitCode'); |
| 644 }); | 733 }); |
| 645 debuggerMain(); | 734 debuggerMain(); |
| 646 }); | 735 }); |
| 647 } else { | 736 } else { |
| 648 debuggerMain(); | 737 debuggerMain(); |
| 649 } | 738 } |
| 650 } | 739 } |
| OLD | NEW |