aboutsummaryrefslogtreecommitdiff
path: root/jerry-debugger
diff options
context:
space:
mode:
authorZoltan Herczeg <zherczeg.u-szeged@partner.samsung.com>2017-02-28 09:25:26 +0100
committerTilmann Scheller <t.scheller@samsung.com>2017-02-28 09:25:26 +0100
commit6efe39c83c26128a3f13b154774c332d7a1247a6 (patch)
treef36e99ab672bb6d965a9df9adfd010afe04ddc54 /jerry-debugger
parentc6a7765690e45032eedb3c9219ad5f8fe5f6a4f1 (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.html113
-rwxr-xr-xjerry-debugger/jerry-client-ws.py83
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)