Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: tools/ddbg.dart

Issue 69343017: Add support for command-line editing to ddbg. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/ddbg/bin/ddbg.dart » ('j') | tools/ddbg/bin/ddbg.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/ddbg.dart
===================================================================
--- tools/ddbg.dart (revision 30481)
+++ tools/ddbg.dart (working copy)
@@ -1,650 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Simple interactive debugger shell that connects to the Dart VM's debugger
-// connection port.
-
-import "dart:convert";
-import "dart:io";
-import "dart:async";
-
-
-Map<int, Completer> outstandingCommands;
-
-Socket vmSock;
-String vmData;
-var stdinSubscription;
-var vmSubscription;
-int seqNum = 0;
-int isolate_id = -1;
-
-final verbose = false;
-final printMessages = false;
-
-// The location of the last paused event.
-Map pausedLocation = null;
-
-
-void printHelp() {
- print("""
- q Quit debugger shell
- bt Show backtrace
- r Resume execution
- s Single step
- so Step over
- si Step into
- sbp [<file>] <line> Set breakpoint
- rbp <id> Remove breakpoint with given id
- po <id> Print object info for given id
- eval obj <id> <expr> Evaluate expr on object id
- eval cls <id> <expr> Evaluate expr on class id
- eval lib <id> <expr> Evaluate expr in toplevel of library id
- pl <id> <idx> [<len>] Print list element/slice
- pc <id> Print class info for given id
- ll List loaded libraries
- plib <id> Print library info for given library id
- slib <id> <true|false> Set library id debuggable
- pg <id> Print all global variables visible within given library id
- ls <lib_id> List loaded scripts in library
- gs <lib_id> <script_url> Get source text of script in library
- tok <lib_id> <script_url> Get line and token table of script in library
- epi <none|all|unhandled> Set exception pause info
- li List ids of all isolates in the VM
- i <id> Interrupt execution of given isolate id
- h Print help
-""");
-}
-
-
-void quitShell() {
- vmSubscription.cancel();
- vmSock.close();
- stdinSubscription.cancel();
-}
-
-
-Future sendCmd(Map<String, dynamic> cmd) {
- var completer = new Completer();
- int id = cmd["id"];
- outstandingCommands[id] = completer;
- if (verbose) {
- print("sending: '${JSON.encode(cmd)}'");
- }
- vmSock.write(JSON.encode(cmd));
- return completer.future;
-}
-
-void processCommand(String cmdLine) {
-
- void huh() {
- print("'$cmdLine' not understood, try h for help");
- }
-
- seqNum++;
- var args = cmdLine.split(' ');
- if (args.length == 0) {
- return;
- }
- var command = args[0];
- var simple_commands =
- { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'};
- if (simple_commands[command] != null) {
- var cmd = { "id": seqNum,
- "command": simple_commands[command],
- "params": { "isolateId" : isolate_id } };
- sendCmd(cmd).then((result) => handleGenericResponse(result));
- } else if (command == "bt") {
- var cmd = { "id": seqNum,
- "command": "getStackTrace",
- "params": { "isolateId" : isolate_id } };
- sendCmd(cmd).then((result) => handleStackTraceResponse(result));
- } else if (command == "ll") {
- var cmd = { "id": seqNum,
- "command": "getLibraries",
- "params": { "isolateId" : isolate_id } };
- sendCmd(cmd).then((result) => handleGetLibraryResponse(result));
- } else if (command == "sbp" && args.length >= 2) {
- var url, line;
- if (args.length == 2 && pausedLocation != null) {
- url = pausedLocation["url"];
- assert(url != null);
- line = int.parse(args[1]);
- } else {
- url = args[1];
- line = int.parse(args[2]);
- }
- var cmd = { "id": seqNum,
- "command": "setBreakpoint",
- "params": { "isolateId" : isolate_id,
- "url": url,
- "line": line }};
- sendCmd(cmd).then((result) => handleSetBpResponse(result));
- } else if (command == "rbp" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "removeBreakpoint",
- "params": { "isolateId" : isolate_id,
- "breakpointId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGenericResponse(result));
- } else if (command == "ls" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "getScriptURLs",
- "params": { "isolateId" : isolate_id,
- "libraryId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGetScriptsResponse(result));
- } else if (command == "eval" && args.length > 3) {
- var expr = args.getRange(3, args.length).join(" ");
- var target = args[1];
- if (target == "obj") {
- target = "objectId";
- } else if (target == "cls") {
- target = "classId";
- } else if (target == "lib") {
- target = "libraryId";
- } else {
- huh();
- return;
- }
- var cmd = { "id": seqNum,
- "command": "evaluateExpr",
- "params": { "isolateId": isolate_id,
- target: int.parse(args[2]),
- "expression": expr } };
- sendCmd(cmd).then((result) => handleEvalResponse(result));
- } else if (command == "po" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "getObjectProperties",
- "params": { "isolateId" : isolate_id,
- "objectId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGetObjPropsResponse(result));
- } else if (command == "pl" && args.length >= 3) {
- var cmd;
- if (args.length == 3) {
- cmd = { "id": seqNum,
- "command": "getListElements",
- "params": { "isolateId" : isolate_id,
- "objectId": int.parse(args[1]),
- "index": int.parse(args[2]) } };
- } else {
- cmd = { "id": seqNum,
- "command": "getListElements",
- "params": { "isolateId" : isolate_id,
- "objectId": int.parse(args[1]),
- "index": int.parse(args[2]),
- "length": int.parse(args[3]) } };
- }
- sendCmd(cmd).then((result) => handleGetListResponse(result));
- } else if (command == "pc" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "getClassProperties",
- "params": { "isolateId" : isolate_id,
- "classId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGetClassPropsResponse(result));
- } else if (command == "plib" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "getLibraryProperties",
- "params": {"isolateId" : isolate_id,
- "libraryId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGetLibraryPropsResponse(result));
- } else if (command == "slib" && args.length == 3) {
- var cmd = { "id": seqNum,
- "command": "setLibraryProperties",
- "params": {"isolateId" : isolate_id,
- "libraryId": int.parse(args[1]),
- "debuggingEnabled": args[2] } };
- sendCmd(cmd).then((result) => handleSetLibraryPropsResponse(result));
- } else if (command == "pg" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "getGlobalVariables",
- "params": { "isolateId" : isolate_id,
- "libraryId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGetGlobalVarsResponse(result));
- } else if (command == "gs" && args.length == 3) {
- var cmd = { "id": seqNum,
- "command": "getScriptSource",
- "params": { "isolateId" : isolate_id,
- "libraryId": int.parse(args[1]),
- "url": args[2] } };
- sendCmd(cmd).then((result) => handleGetSourceResponse(result));
- } else if (command == "tok" && args.length == 3) {
- var cmd = { "id": seqNum,
- "command": "getLineNumberTable",
- "params": { "isolateId" : isolate_id,
- "libraryId": int.parse(args[1]),
- "url": args[2] } };
- sendCmd(cmd).then((result) => handleGetLineTableResponse(result));
- } else if (command == "epi" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "setPauseOnException",
- "params": { "isolateId" : isolate_id,
- "exceptions": args[1] } };
- sendCmd(cmd).then((result) => handleGenericResponse(result));
- } else if (command == "li") {
- var cmd = { "id": seqNum, "command": "getIsolateIds" };
- sendCmd(cmd).then((result) => handleGetIsolatesResponse(result));
- } else if (command == "i" && args.length == 2) {
- var cmd = { "id": seqNum,
- "command": "interrupt",
- "params": { "isolateId": int.parse(args[1]) } };
- sendCmd(cmd).then((result) => handleGenericResponse(result));
- } else if (command == "q") {
- quitShell();
- } else if (command == "h") {
- printHelp();
- } else {
- huh();
- }
-}
-
-
-String remoteObject(value) {
- var kind = value["kind"];
- var text = value["text"];
- var id = value["objectId"];
- if (kind == "string") {
- return "(string, id $id) '$text'";
- } else if (kind == "list") {
- var len = value["length"];
- return "(list, id $id, len $len) $text";
- } else if (kind == "object") {
- return "(obj, id $id) $text";
- } else if (kind == "function") {
- var location = value['location'] != null
- ? ", file '${value['location']['url']}'"
- ", token pos ${value['location']['tokenOffset']}"
- : "";
- var name = value['name'];
- var signature = value['signature'];
- return "(closure ${name}${signature} $location)";
- } else {
- return "$text";
- }
-}
-
-
-printNamedObject(obj) {
- var name = obj["name"];
- var value = obj["value"];
- print(" $name = ${remoteObject(value)}");
-}
-
-
-handleGetObjPropsResponse(response) {
- Map props = response["result"];
- int class_id = props["classId"];
- if (class_id == -1) {
- print(" null");
- return;
- }
- List fields = props["fields"];
- print(" class id: $class_id");
- for (int i = 0; i < fields.length; i++) {
- printNamedObject(fields[i]);
- }
-}
-
-handleGetListResponse(response) {
- Map result = response["result"];
- if (result["elements"] != null) {
- // List slice.
- var index = result["index"];
- var length = result["length"];
- List elements = result["elements"];
- assert(length == elements.length);
- for (int i = 0; i < length; i++) {
- var kind = elements[i]["kind"];
- var text = elements[i]["text"];
- print(" ${index + i}: ($kind) $text");
- }
- } else {
- // One element, a remote object.
- print(result);
- print(" ${remoteObject(result)}");
- }
-}
-
-
-handleGetClassPropsResponse(response) {
- Map props = response["result"];
- assert(props["name"] != null);
- int libId = props["libraryId"];
- assert(libId != null);
- print(" class ${props["name"]} (library id: $libId)");
- List fields = props["fields"];
- if (fields.length > 0) {
- print(" static fields:");
- for (int i = 0; i < fields.length; i++) {
- printNamedObject(fields[i]);
- }
- }
-}
-
-
-handleGetLibraryPropsResponse(response) {
- Map props = response["result"];
- assert(props["url"] != null);
- print(" library url: ${props["url"]}");
- assert(props["debuggingEnabled"] != null);
- print(" debugging enabled: ${props["debuggingEnabled"]}");
- List imports = props["imports"];
- assert(imports != null);
- if (imports.length > 0) {
- print(" imports:");
- for (int i = 0; i < imports.length; i++) {
- print(" id ${imports[i]["libraryId"]} prefix ${imports[i]["prefix"]}");
- }
- }
- List globals = props["globals"];
- assert(globals != null);
- if (globals.length > 0) {
- print(" global variables:");
- for (int i = 0; i < globals.length; i++) {
- printNamedObject(globals[i]);
- }
- }
-}
-
-
-handleSetLibraryPropsResponse(response) {
- Map props = response["result"];
- assert(props["debuggingEnabled"] != null);
- print(" debugging enabled: ${props["debuggingEnabled"]}");
-}
-
-
-handleGetGlobalVarsResponse(response) {
- List globals = response["result"]["globals"];
- for (int i = 0; i < globals.length; i++) {
- printNamedObject(globals[i]);
- }
-}
-
-
-handleGetSourceResponse(response) {
- Map result = response["result"];
- String source = result["text"];
- print("Source text:\n$source\n--------");
-}
-
-
-handleGetLineTableResponse(response) {
- Map result = response["result"];
- var info = result["lines"];
- print("Line info table:\n$info");
-}
-
-
-handleGetIsolatesResponse(response) {
- Map result = response["result"];
- print("Isolates: ${result["isolateIds"]}");
-}
-
-
-void handleGetLibraryResponse(response) {
- Map result = response["result"];
- List libs = result["libraries"];
- print("Loaded libraries:");
- print(libs);
- for (int i = 0; i < libs.length; i++) {
- print(" ${libs[i]["id"]} ${libs[i]["url"]}");
- }
-}
-
-
-void handleGetScriptsResponse(response) {
- Map result = response["result"];
- List urls = result["urls"];
- print("Loaded scripts:");
- for (int i = 0; i < urls.length; i++) {
- print(" $i ${urls[i]}");
- }
-}
-
-
-void handleEvalResponse(response) {
- Map result = response["result"];
- print(remoteObject(result));
-}
-
-
-void handleSetBpResponse(response) {
- Map result = response["result"];
- var id = result["breakpointId"];
- assert(id != null);
- print("Set BP $id");
-}
-
-
-void handleGenericResponse(response) {
- if (response["error"] != null) {
- print("Error: ${response["error"]}");
- }
-}
-
-
-void handleStackTraceResponse(response) {
- Map result = response["result"];
- List callFrames = result["callFrames"];
- assert(callFrames != null);
- printStackTrace(callFrames);
-}
-
-
-void printStackFrame(frame_num, Map frame) {
- var fname = frame["functionName"];
- var libId = frame["location"]["libraryId"];
- var url = frame["location"]["url"];
- var toff = frame["location"]["tokenOffset"];
- print("$frame_num $fname (url: $url token: $toff lib: $libId)");
- List locals = frame["locals"];
- for (int i = 0; i < locals.length; i++) {
- printNamedObject(locals[i]);
- }
-}
-
-
-void printStackTrace(List frames) {
- for (int i = 0; i < frames.length; i++) {
- printStackFrame(i, frames[i]);
- }
-}
-
-
-void handlePausedEvent(msg) {
- assert(msg["params"] != null);
- var reason = msg["params"]["reason"];
- isolate_id = msg["params"]["isolateId"];
- assert(isolate_id != null);
- pausedLocation = msg["params"]["location"];
- assert(pausedLocation != null);
- if (reason == "breakpoint") {
- print("Isolate $isolate_id paused on breakpoint");
- print("location: $pausedLocation");
- } else if (reason == "interrupted") {
- print("Isolate $isolate_id paused due to an interrupt");
- } else {
- assert(reason == "exception");
- var excObj = msg["params"]["exception"];
- print("Isolate $isolate_id paused on exception");
- print(remoteObject(excObj));
- }
-}
-
-
-void processVmMessage(String jsonString) {
- var msg = JSON.decode(jsonString);
- if (msg == null) {
- return;
- }
- var event = msg["event"];
- if (event == "paused") {
- handlePausedEvent(msg);
- return;
- }
- if (event == "breakpointResolved") {
- Map params = msg["params"];
- assert(params != null);
- print("BP ${params["breakpointId"]} resolved and "
- "set at line ${params["line"]}.");
- return;
- }
- if (event == "isolate") {
- Map params = msg["params"];
- assert(params != null);
- print("Isolate ${params["id"]} has been ${params["reason"]}.");
- return;
- }
- if (msg["id"] != null) {
- var id = msg["id"];
- if (outstandingCommands.containsKey(id)) {
- if (msg["error"] != null) {
- print("VM says: ${msg["error"]}");
- } else {
- var completer = outstandingCommands[id];
- completer.complete(msg);
- }
- outstandingCommands.remove(id);
- }
- }
-}
-
-bool haveGarbageVmData() {
- if (vmData == null || vmData.length == 0) return false;
- var i = 0, char = " ";
- while (i < vmData.length) {
- char = vmData[i];
- if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
- i++;
- }
- if (i >= vmData.length) {
- return false;
- } else {
- return char != "{";
- }
-}
-
-
-void processVmData(String data) {
- if (vmData == null || vmData.length == 0) {
- vmData = data;
- } else {
- vmData = vmData + data;
- }
- if (haveGarbageVmData()) {
- print("Error: have garbage data from VM: '$vmData'");
- return;
- }
- int msg_len = jsonObjectLength(vmData);
- if (printMessages && msg_len == 0) {
- print("have partial or illegal json message"
- " of ${vmData.length} chars:\n'$vmData'");
- return;
- }
- while (msg_len > 0 && msg_len <= vmData.length) {
- if (msg_len == vmData.length) {
- if (printMessages) { print("have one full message:\n$vmData"); }
- processVmMessage(vmData);
- vmData = null;
- return;
- }
- if (printMessages) { print("at least one message: '$vmData'"); }
- var msg = vmData.substring(0, msg_len);
- if (printMessages) { print("first message: $msg"); }
- vmData = vmData.substring(msg_len);
- if (haveGarbageVmData()) {
- print("Error: garbage data after previous message: '$vmData'");
- print("Previous message was: '$msg'");
- return;
- }
- processVmMessage(msg);
- msg_len = jsonObjectLength(vmData);
- }
- if (printMessages) { print("leftover vm data '$vmData'"); }
-}
-
-/**
- * Skip past a JSON object value.
- * The object value must start with '{' and continues to the
- * matching '}'. No attempt is made to otherwise validate the contents
- * as JSON. If it is invalid, a later [parseJson] will fail.
- */
-int jsonObjectLength(String string) {
- int skipWhitespace(int index) {
- while (index < string.length) {
- String char = string[index];
- if (char != " " && char != "\n" && char != "\r" && char != "\t") break;
- index++;
- }
- return index;
- }
- int skipString(int index) {
- assert(string[index - 1] == '"');
- while (index < string.length) {
- String char = string[index];
- if (char == '"') return index + 1;
- if (char == r'\') index++;
- if (index == string.length) return index;
- index++;
- }
- return index;
- }
- int index = 0;
- index = skipWhitespace(index);
- // Bail out if the first non-whitespace character isn't '{'.
- if (index == string.length || string[index] != '{') return 0;
- int nesting = 0;
- while (index < string.length) {
- String char = string[index++];
- if (char == '{') {
- nesting++;
- } else if (char == '}') {
- nesting--;
- if (nesting == 0) return index;
- } else if (char == '"') {
- // Strings can contain braces. Skip their content.
- index = skipString(index);
- }
- }
- return 0;
-}
-
-
-void debuggerMain() {
- outstandingCommands = new Map<int, Completer>();
- Socket.connect("127.0.0.1", 5858).then((s) {
- vmSock = s;
- vmSock.setOption(SocketOption.TCP_NODELAY, true);
- var stringStream = vmSock.transform(UTF8.decoder);
- vmSubscription = stringStream.listen(
- (String data) {
- processVmData(data);
- },
- onDone: () {
- print("VM debugger connection closed");
- quitShell();
- },
- onError: (err) {
- print("Error in debug connection: $err");
- // TODO(floitsch): do we want to print the stack trace?
- quitShell();
- });
- stdinSubscription = stdin.transform(UTF8.decoder)
- .transform(new LineSplitter())
- .listen((String line) => processCommand(line));
- });
-}
-
-void main(List<String> arguments) {
- if (arguments.length > 0) {
- arguments = <String>['--debug', '--verbose_debug']..addAll(arguments);
- Process.start(Platform.executable, arguments).then((Process process) {
- process.stdin.close();
- process.exitCode.then((int exitCode) {
- print('${arguments.join(" ")} exited with $exitCode');
- });
- debuggerMain();
- });
- } else {
- debuggerMain();
- }
-}
« no previous file with comments | « no previous file | tools/ddbg/bin/ddbg.dart » ('j') | tools/ddbg/bin/ddbg.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698