Chromium Code Reviews| Index: tools/ddbg.dart |
| =================================================================== |
| --- tools/ddbg.dart (revision 7818) |
| +++ tools/ddbg.dart (working copy) |
| @@ -16,7 +16,14 @@ |
| bool verbose = false; |
| +// The current stack trace, while the VM is paused. It's a list |
| +// of activation frames. |
| +List stackTrace; |
| +// The current activation frame, while the VM is paused. |
| +Map curFrame; |
| + |
| + |
| void printHelp() { |
| print(""" |
| q Quit debugger shell |
| @@ -25,7 +32,8 @@ |
| s Single step |
| so Step over |
| si Step into |
| - sbp <file> <line> Set breakpoint |
| + sbp [<file>] <line> Set breakpoint |
| + po <id> Print object |
|
siva
2012/05/22 01:49:09
missing help for command 'pc' ?
Also noticed 'h'
hausner
2012/05/22 18:03:57
Done.
|
| ll List loaded libraries |
| ls <libname> List loaded scripts in library |
| """); |
| @@ -62,37 +70,51 @@ |
| if (cmd == "r") { |
| var cmd = { "id": seqNum, "command": "resume" }; |
| sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| + stackTrace = curFrame = null; |
| } else if (cmd == "s") { |
| var cmd = { "id": seqNum, "command": "stepOver" }; |
| sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| + stackTrace = curFrame = null; |
| } else if (cmd == "si") { |
| var cmd = { "id": seqNum, "command": "stepInto" }; |
| sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| + stackTrace = curFrame = null; |
| } else if (cmd == "so") { |
| var cmd = { "id": seqNum, "command": "stepOut" }; |
| sendCmd(cmd).then((result) => handleGenericResponse(result)); |
| + stackTrace = curFrame = null; |
| } else if (cmd == "bt") { |
| var cmd = { "id": seqNum, "command": "getStackTrace" }; |
| sendCmd(cmd).then((result) => handleStackTraceResponse(result)); |
| } else if (cmd == "ll") { |
| var cmd = { "id": seqNum, "command": "getLibraryURLs" }; |
| sendCmd(cmd).then((result) => handleGetLibraryResponse(result)); |
| - } else if (cmd == "sbp") { |
| - if (args.length < 3) { |
| - return; |
| + } else if (cmd == "sbp" && args.length >= 2) { |
| + var url, line; |
| + if (args.length == 2) { |
| + url = stackTrace[0]["location"]["url"]; |
| + line = Math.parseInt(args[1]); |
| + } else { |
| + url = args[1]; |
| + line = Math.parseInt(args[2]); |
| } |
| var cmd = { "id": seqNum, |
| "command": "setBreakpoint", |
| - "params": { "url": args[1], "line": Math.parseInt(args[2]) }}; |
| + "params": { "url": url, "line": line }}; |
| sendCmd(cmd).then((result) => handleSetBpResponse(result)); |
| - } else if (cmd == "ls") { |
| - if (args.length < 2) { |
| - return; |
| - } |
| + } else if (cmd == "ls" && args.length == 2) { |
| var cmd = { "id": seqNum, |
| "command": "getScriptURLs", |
| "params": { "library": args[1] }}; |
| sendCmd(cmd).then((result) => handleGetScriptsResponse(result)); |
| + } else if (cmd == "po" && args.length == 2) { |
| + var cmd = { "id": seqNum, "command": "getObjectProperties", |
| + "params": {"objectId": Math.parseInt(args[1]) }}; |
| + sendCmd(cmd).then((result) => handleGetObjPropsResponse(result)); |
| + } else if (cmd == "pc" && args.length == 2) { |
| + var cmd = { "id": seqNum, "command": "getClassProperties", |
| + "params": {"classId": Math.parseInt(args[1]) }}; |
| + sendCmd(cmd).then((result) => handleGetClassPropsResponse(result)); |
| } else if (cmd == "q") { |
| quitShell(); |
| } else if (cmd == "h") { |
| @@ -103,6 +125,56 @@ |
| } |
| +printNamedObject(obj) { |
| + var name = obj["name"]; |
| + var value = obj["value"]; |
| + var kind = value["kind"]; |
| + var text = value["text"]; |
| + var id = value["objectId"]; |
| + if (kind == "string") { |
| + print(" $name = '$text'"); |
| + } else if (kind == "object") { |
| + print(" $name (id:$id) = $text"); |
| + } else { |
| + print(" $name = $text"); |
| + } |
| +} |
| + |
| + |
| +handleGetObjPropsResponse(response) { |
| + var props = response["result"]; |
| + assert(props != null); |
| + var class_id = props["classId"]; |
| + assert(class_id != null); |
| + var fields = props["fields"]; |
| + assert(fields != null); |
|
siva
2012/05/22 01:49:09
Just curious, what is the point of this assert, wo
hausner
2012/05/22 18:03:57
I guess so. Old C++ habits...
|
| + assert(fields is List); |
|
siva
2012/05/22 01:49:09
Also what is the style here? instead of adding our
hausner
2012/05/22 18:03:57
This is my early code in which I was experimenting
|
| + print(" class id: $class_id"); |
| + for (int i = 0; i < fields.length; i++) { |
| + printNamedObject(fields[i]); |
| + } |
| +} |
| + |
| + |
| +handleGetClassPropsResponse(response) { |
| + var props = response["result"]; |
| + assert(props != null); |
| + assert(props["name"] != null); |
| + var libId = props["libraryId"]; |
| + assert(libId != null); |
| + print(" class ${props["name"]} (library id: $libId)"); |
| + var fields = props["fields"]; |
| + assert(fields != null); |
| + assert(fields is List); |
| + if (fields.length > 0) { |
| + print(" static fields:"); |
| + for (int i = 0; i < fields.length; i++) { |
| + printNamedObject(fields[i]); |
| + } |
| + } |
| +} |
| + |
| + |
| void handleGetLibraryResponse(response) { |
| var result = response["result"]; |
| assert(result != null); |
| @@ -150,27 +222,41 @@ |
| assert(result != null); |
| var callFrames = result["callFrames"]; |
| assert(callFrames != null); |
| - printStackTrace(result); |
| + printStackTrace(callFrames); |
| } |
| -void printStackTrace(trace) { |
| - assert(trace != null); |
| - var frames = trace["callFrames"]; |
| - if (frames is !List) { |
| - print("unexpected type for frames parameter $frames"); |
| - return; |
| +void printStackFrame(frame_num, frame) { |
| + var fname = frame["functionName"]; |
| + var url = frame["location"]["url"]; |
| + var line = frame["location"]["lineNumber"]; |
| + print("$frame_num $fname ($url:$line)"); |
| + var locals = frame["locals"]; |
| + assert(locals is List); |
|
siva
2012/05/22 01:49:09
Ditto question about explicit type check assert.
hausner
2012/05/22 18:03:57
Done.
|
| + for (int i = 0; i < locals.length; i++) { |
| + printNamedObject(locals[i]); |
| } |
| +} |
| + |
| + |
| +void printStackTrace(List frames) { |
| for (int i = 0; i < frames.length; i++) { |
| - var frame = frames[i]; |
| - var fname = frame["functionName"]; |
| - var url = frame["location"]["url"]; |
| - var line = frame["location"]["lineNumber"]; |
| - print("$i $fname ($url:$line)"); |
| + printStackFrame(i, frames[i]); |
| } |
| } |
| +void handlePausedEvent(msg) { |
| + assert(msg["params"] != null); |
| + stackTrace = msg["params"]["callFrames"]; |
| + assert(stackTrace != null); |
| + assert(stackTrace.length >= 1); |
| + curFrame = stackTrace[0]; |
| + print("VM paused, stack trace:"); |
| + printStackTrace(stackTrace); |
| +} |
| + |
| + |
| void processVmMessage(String json) { |
| var msg = JSON.parse(json); |
| if (msg == null) { |
| @@ -178,8 +264,7 @@ |
| } |
| var event = msg["event"]; |
| if (event == "paused") { |
| - print("VM paused, stack trace:"); |
| - printStackTrace(msg["params"]); |
| + handlePausedEvent(msg); |
| return; |
| } |
| if (event == "breakpointResolved") { |