diff options
author | Zoltan Herczeg <zherczeg.u-szeged@partner.samsung.com> | 2017-02-28 09:25:26 +0100 |
---|---|---|
committer | Tilmann Scheller <t.scheller@samsung.com> | 2017-02-28 09:25:26 +0100 |
commit | 6efe39c83c26128a3f13b154774c332d7a1247a6 (patch) | |
tree | f36e99ab672bb6d965a9df9adfd010afe04ddc54 /jerry-debugger | |
parent | c6a7765690e45032eedb3c9219ad5f8fe5f6a4f1 (diff) |
Add source code support to the debugger. (#1614)
Besides the breakpoint list the JavaScript source code is
also sent to the debugger. This feature allows debugging
eval() function calls.
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
Diffstat (limited to 'jerry-debugger')
-rw-r--r-- | jerry-debugger/jerry-client-ws.html | 113 | ||||
-rwxr-xr-x | jerry-debugger/jerry-client-ws.py | 83 |
2 files changed, 122 insertions, 74 deletions
diff --git a/jerry-debugger/jerry-client-ws.html b/jerry-debugger/jerry-client-ws.html index 0792eaeb..93217bd8 100644 --- a/jerry-debugger/jerry-client-ws.html +++ b/jerry-debugger/jerry-client-ws.html @@ -34,18 +34,20 @@ var JERRY_DEBUGGER_BYTE_CODE_CP = 3; var JERRY_DEBUGGER_PARSE_FUNCTION = 4; var JERRY_DEBUGGER_BREAKPOINT_LIST = 5; var JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6; -var JERRY_DEBUGGER_RESOURCE_NAME = 7; -var JERRY_DEBUGGER_RESOURCE_NAME_END = 8; -var JERRY_DEBUGGER_FUNCTION_NAME = 9; -var JERRY_DEBUGGER_FUNCTION_NAME_END = 10; -var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 11; -var JERRY_DEBUGGER_BREAKPOINT_HIT = 12; -var JERRY_DEBUGGER_BACKTRACE = 13; -var JERRY_DEBUGGER_BACKTRACE_END = 14; -var JERRY_DEBUGGER_EVAL_RESULT = 15; -var JERRY_DEBUGGER_EVAL_RESULT_END = 16; -var JERRY_DEBUGGER_EVAL_ERROR = 17; -var JERRY_DEBUGGER_EVAL_ERROR_END = 18; +var JERRY_DEBUGGER_SOURCE_CODE = 7; +var JERRY_DEBUGGER_SOURCE_CODE_END = 8; +var JERRY_DEBUGGER_SOURCE_CODE_NAME = 9; +var JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10; +var JERRY_DEBUGGER_FUNCTION_NAME = 11; +var JERRY_DEBUGGER_FUNCTION_NAME_END = 12; +var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13; +var JERRY_DEBUGGER_BREAKPOINT_HIT = 14; +var JERRY_DEBUGGER_BACKTRACE = 15; +var JERRY_DEBUGGER_BACKTRACE_END = 16; +var JERRY_DEBUGGER_EVAL_RESULT = 17; +var JERRY_DEBUGGER_EVAL_RESULT_END = 18; +var JERRY_DEBUGGER_EVAL_ERROR = 19; +var JERRY_DEBUGGER_EVAL_ERROR_END = 20; var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1; var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2; @@ -81,6 +83,7 @@ function DebuggerClient(address) var littleEndian = true; var functions = { }; var lineList = new Multimap(); + var lastBreakpointHit = null; var activeBreakpoints = { }; var nextBreakpointIndex = 1; var backtraceFrame = 0; @@ -239,7 +242,7 @@ function DebuggerClient(address) { var name = breakpoint.func.name; - var result = breakpoint.func.resource; + var result = breakpoint.func.sourceName; if (!result) { @@ -465,9 +468,12 @@ function DebuggerClient(address) function ParseSource() { - var resourceName = null; + var source = ""; + var sourceData = null; + var sourceName = ""; + var sourceNameData = null; var functionName = null; - var stack = [ { name: '', lines: [], offsets: [] } ]; + var stack = [ { name: "", source: "", lines: [], offsets: [] } ]; var newFunctions = [ ]; this.receive = function(message) @@ -481,19 +487,26 @@ function DebuggerClient(address) return; } - case JERRY_DEBUGGER_RESOURCE_NAME: - case JERRY_DEBUGGER_RESOURCE_NAME_END: + case JERRY_DEBUGGER_SOURCE_CODE: + case JERRY_DEBUGGER_SOURCE_CODE_END: { - if ((typeof resourceName) == "string") + sourceData = concatUint8Arrays(sourceData, message); + + if (message[0] == JERRY_DEBUGGER_SOURCE_CODE_END) { - abortConnection("unexpected message."); + source = cesu8ToString(sourceData); } + return; + } - resourceName = concatUint8Arrays(resourceName, message); + case JERRY_DEBUGGER_SOURCE_CODE_NAME: + case JERRY_DEBUGGER_SOURCE_CODE_NAME_END: + { + sourceNameData = concatUint8Arrays(sourceNameData, message); - if (message[0] == JERRY_DEBUGGER_RESOURCE_NAME_END) + if (message[0] == JERRY_DEBUGGER_SOURCE_CODE_NAME_END) { - resourceName = cesu8ToString(resourceName); + sourceName = cesu8ToString(sourceNameData); } return; } @@ -507,16 +520,11 @@ function DebuggerClient(address) case JERRY_DEBUGGER_PARSE_FUNCTION: { - if (resourceName == null) - { - resourceName = ""; - } - else if ((typeof resourceName) != "string") - { - abortConnection("unexpected message."); - } - - stack.push({ name: cesu8ToString(functionName), resource: resourceName, lines: [], offsets: [] }); + stack.push({ name: cesu8ToString(functionName), + source: source, + sourceName: sourceName, + lines: [], + offsets: [] }); functionName = null; return; } @@ -575,7 +583,8 @@ function DebuggerClient(address) return; } - func.resource = resourceName; + func.source = source; + func.sourceName = sourceName; break; } @@ -644,8 +653,10 @@ function DebuggerClient(address) case JERRY_DEBUGGER_BYTE_CODE_CP: case JERRY_DEBUGGER_PARSE_FUNCTION: case JERRY_DEBUGGER_BREAKPOINT_LIST: - case JERRY_DEBUGGER_RESOURCE_NAME: - case JERRY_DEBUGGER_RESOURCE_NAME_END: + case JERRY_DEBUGGER_SOURCE_CODE: + case JERRY_DEBUGGER_SOURCE_CODE_END: + case JERRY_DEBUGGER_SOURCE_CODE_NAME: + case JERRY_DEBUGGER_SOURCE_CODE_NAME_END: case JERRY_DEBUGGER_FUNCTION_NAME: case JERRY_DEBUGGER_FUNCTION_NAME_END: { @@ -686,8 +697,9 @@ function DebuggerClient(address) breakpoint = functions[breakpoint[0]].offsets[breakpoint[1]]; - breakpointIndex = ""; + lastBreakpointHit = breakpoint; + breakpointIndex = ""; if (breakpoint.activeIndex >= 0) { breakpointIndex = "breakpoint:" + breakpoint.activeIndex + " "; @@ -800,11 +812,11 @@ function DebuggerClient(address) for (var i = 0; i < functionList.length; ++i) { var func = functionList[i]; - var resource = func.resource; + var sourceName = func.sourceName; - if (resource == line[1] - || resource.endsWith("/" + line[1]) - || resource.endsWith("\\" + line[1])) + if (sourceName == line[1] + || sourceName.endsWith("/" + line[1]) + || sourceName.endsWith("\\" + line[1])) { insertBreakpoint(func.lines[line[2]]); } @@ -894,19 +906,27 @@ function DebuggerClient(address) } } + this.printSource = function() + { + if (lastBreakpointHit) + { + appendLog(lastBreakpointHit.func.source); + } + } + this.dump = function() { for (var i in functions) { var func = functions[i]; - var resource = func.resource; + var sourceName = func.sourceName; - if (resource == '') + if (!sourceName) { - resource = "<unknown>"; + sourceName = "<unknown>"; } - appendLog("Function 0x" + Number(i).toString(16) + " '" + func.name + "' at " + resource + ":" + func.firstLine); + appendLog("Function 0x" + Number(i).toString(16) + " '" + func.name + "' at " + sourceName + ":" + func.firstLine); for (var j in func.lines) { @@ -958,6 +978,7 @@ function debuggerCommand(event) " next|n - connect to server\n" + " eval|e - evaluate expression\n" + " backtrace|bt <max-depth> - get backtrace\n" + + " src - print current source code\n" + " dump - dump all breakpoint data"); commandBox.value = ""; @@ -1063,6 +1084,10 @@ function debuggerCommand(event) debuggerObj.encodeMessage("BI", [ JERRY_DEBUGGER_GET_BACKTRACE, max_depth ]); break; + case "src": + debuggerObj.printSource(); + break; + case "list": debuggerObj.listBreakpoints(); break; diff --git a/jerry-debugger/jerry-client-ws.py b/jerry-debugger/jerry-client-ws.py index 1ecc9b67..6ba7887d 100755 --- a/jerry-debugger/jerry-client-ws.py +++ b/jerry-debugger/jerry-client-ws.py @@ -31,18 +31,20 @@ JERRY_DEBUGGER_BYTE_CODE_CP = 3 JERRY_DEBUGGER_PARSE_FUNCTION = 4 JERRY_DEBUGGER_BREAKPOINT_LIST = 5 JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6 -JERRY_DEBUGGER_RESOURCE_NAME = 7 -JERRY_DEBUGGER_RESOURCE_NAME_END = 8 -JERRY_DEBUGGER_FUNCTION_NAME = 9 -JERRY_DEBUGGER_FUNCTION_NAME_END = 10 -JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 11 -JERRY_DEBUGGER_BREAKPOINT_HIT = 12 -JERRY_DEBUGGER_BACKTRACE = 13 -JERRY_DEBUGGER_BACKTRACE_END = 14 -JERRY_DEBUGGER_EVAL_RESULT = 15 -JERRY_DEBUGGER_EVAL_RESULT_END = 16 -JERRY_DEBUGGER_EVAL_ERROR = 17 -JERRY_DEBUGGER_EVAL_ERROR_END = 18 +JERRY_DEBUGGER_SOURCE_CODE = 7 +JERRY_DEBUGGER_SOURCE_CODE_END = 8 +JERRY_DEBUGGER_SOURCE_CODE_NAME = 9 +JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10 +JERRY_DEBUGGER_FUNCTION_NAME = 11 +JERRY_DEBUGGER_FUNCTION_NAME_END = 12 +JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13 +JERRY_DEBUGGER_BREAKPOINT_HIT = 14 +JERRY_DEBUGGER_BACKTRACE = 15 +JERRY_DEBUGGER_BACKTRACE_END = 16 +JERRY_DEBUGGER_EVAL_RESULT = 17 +JERRY_DEBUGGER_EVAL_RESULT_END = 18 +JERRY_DEBUGGER_EVAL_ERROR = 19 +JERRY_DEBUGGER_EVAL_ERROR_END = 20 # Messages sent by the client to server. JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1 @@ -84,7 +86,7 @@ class JerryBreakpoint(object): self.active_index = -1 def to_string(self): - result = self.function.source + result = self.function.source_name if result == "": result = "<unknown>" @@ -102,15 +104,16 @@ class JerryBreakpoint(object): class JerryFunction(object): - def __init__(self, byte_code_cp, source, name, lines, offsets): + def __init__(self, byte_code_cp, source, source_name, name, lines, offsets): self.byte_code_cp = byte_code_cp self.source = source + self.source_name = source_name self.name = name self.lines = {} self.offsets = {} self.first_line = -1 - if len > 0: + if lines: self.first_line = lines[0] for i in range(len(lines)): @@ -121,8 +124,8 @@ class JerryFunction(object): self.offsets[offset] = breakpoint def __repr__(self): - result = ("Function(byte_code_cp:0x%x, source:\"%s\", name:\"%s\", { " - % (self.byte_code_cp, self.source, self.name)) + result = ("Function(byte_code_cp:0x%x, source_name:\"%s\", name:\"%s\", { " + % (self.byte_code_cp, self.source_name, self.name)) result += ','.join([str(breakpoint) for breakpoint in self.lines.values()]) @@ -248,6 +251,11 @@ class DebuggerPrompt(Cmd): """ Get backtrace data from debugger """ self.exec_backtrace(args) + def do_src(self, args): + """ Get current source code """ + if self.debugger.last_breakpoint_hit: + print(self.debugger.last_breakpoint_hit.function.source) + def do_dump(self, args): """ Dump all of the debugger data """ pprint(self.debugger.function_list) @@ -348,6 +356,7 @@ class JerryDebugger(object): self.message_data = b"" self.function_list = {} + self.last_breakpoint_hit = None self.next_breakpoint_index = 0 self.active_breakpoint_list = {} self.line_list = Multimap() @@ -480,7 +489,8 @@ class JerryDebugger(object): def parse_source(debugger, data): - source_name = "" + source_code = "" + source_code_name = "" function_name = "" stack = [{"lines": [], "offsets": [], "name": ""}] new_function_list = {} @@ -498,15 +508,22 @@ def parse_source(debugger, data): logging.error("Parser error!") return - if buffer_type in [JERRY_DEBUGGER_RESOURCE_NAME, JERRY_DEBUGGER_RESOURCE_NAME_END]: - source_name += data[3:] + elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]: + source_code += data[3:] + + elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE_NAME, JERRY_DEBUGGER_SOURCE_CODE_NAME_END]: + source_code_name += data[3:] elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: function_name += data[3:] elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION: - logging.debug("Source name: %s, function name: %s" % (source_name, function_name)) - stack.append({"name": function_name, "source": source_name, "lines": [], "offsets": []}) + logging.debug("Source name: %s, function name: %s" % (source_code_name, function_name)) + stack.append({ "source": source_code, + "source_name": source_code_name, + "name": function_name, + "lines": [], + "offsets": []}) function_name = "" elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]: @@ -534,10 +551,12 @@ def parse_source(debugger, data): # We know the last item in the list is the general byte code. if len(stack) == 0: - func_desc["source"] = source_name + func_desc["source"] = source_code + func_desc["source_name"] = source_code_name function = JerryFunction(byte_code_cp, func_desc["source"], + func_desc["source_name"], func_desc["name"], func_desc["lines"], func_desc["offsets"]) @@ -604,14 +623,14 @@ def set_breakpoint(debugger, string): found = False if line: - source = line.group(1) + source_name = line.group(1) line = int(line.group(2)) for breakpoint in debugger.line_list.get(line): - func_source = breakpoint.function.source - if (source == func_source or - func_source.endswith("/" + source) or - func_source.endswith("\\" + source)): + func_source = breakpoint.function.source_name + if (source_name == func_source or + func_source.endswith("/" + source_name) or + func_source.endswith("\\" + source_name)): enable_breakpoint(debugger, breakpoint) found = True @@ -656,8 +675,10 @@ def main(): JERRY_DEBUGGER_BYTE_CODE_CP, JERRY_DEBUGGER_PARSE_FUNCTION, JERRY_DEBUGGER_BREAKPOINT_LIST, - JERRY_DEBUGGER_RESOURCE_NAME, - JERRY_DEBUGGER_RESOURCE_NAME_END, + JERRY_DEBUGGER_SOURCE_CODE, + JERRY_DEBUGGER_SOURCE_CODE_END, + JERRY_DEBUGGER_SOURCE_CODE_NAME, + JERRY_DEBUGGER_SOURCE_CODE_NAME_END, JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: parse_source(debugger, data) @@ -671,6 +692,8 @@ def main(): function = debugger.function_list[breakpoint_data[0]] breakpoint = function.offsets[breakpoint_data[1]] + debugger.last_breakpoint_hit = breakpoint + breakpoint_index = "" if breakpoint.active_index >= 0: breakpoint_index = " breakpoint:%d" % (breakpoint.active_index) |