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
This commit is contained in:
committed by
Tilmann Scheller
parent
c6a7765690
commit
6efe39c83c
@@ -66,18 +66,20 @@ typedef enum
|
|||||||
JERRY_DEBUGGER_PARSE_FUNCTION = 4, /**< parsing a new function */
|
JERRY_DEBUGGER_PARSE_FUNCTION = 4, /**< parsing a new function */
|
||||||
JERRY_DEBUGGER_BREAKPOINT_LIST = 5, /**< list of line offsets */
|
JERRY_DEBUGGER_BREAKPOINT_LIST = 5, /**< list of line offsets */
|
||||||
JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6, /**< list of byte code offsets */
|
JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6, /**< list of byte code offsets */
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME = 7, /**< resource name fragment */
|
JERRY_DEBUGGER_SOURCE_CODE = 7, /**< source code fragment */
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME_END = 8, /**< resource name fragment */
|
JERRY_DEBUGGER_SOURCE_CODE_END = 8, /**< source code last fragment */
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME = 9, /**< function name fragment */
|
JERRY_DEBUGGER_SOURCE_CODE_NAME = 9, /**< source code name fragment */
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME_END = 10, /**< function name fragment */
|
JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10, /**< source code name last fragment */
|
||||||
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 11, /**< invalidate byte code compressed pointer */
|
JERRY_DEBUGGER_FUNCTION_NAME = 11, /**< function name fragment */
|
||||||
JERRY_DEBUGGER_BREAKPOINT_HIT = 12, /**< notify breakpoint hit */
|
JERRY_DEBUGGER_FUNCTION_NAME_END = 12, /**< function name last fragment */
|
||||||
JERRY_DEBUGGER_BACKTRACE = 13, /**< backtrace data */
|
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13, /**< invalidate byte code compressed pointer */
|
||||||
JERRY_DEBUGGER_BACKTRACE_END = 14, /**< last backtrace data */
|
JERRY_DEBUGGER_BREAKPOINT_HIT = 14, /**< notify breakpoint hit */
|
||||||
JERRY_DEBUGGER_EVAL_RESULT = 15, /**< eval result */
|
JERRY_DEBUGGER_BACKTRACE = 15, /**< backtrace data */
|
||||||
JERRY_DEBUGGER_EVAL_RESULT_END = 16, /**< last part of eval result */
|
JERRY_DEBUGGER_BACKTRACE_END = 16, /**< last backtrace data */
|
||||||
JERRY_DEBUGGER_EVAL_ERROR = 17, /**< eval result when an error is occured */
|
JERRY_DEBUGGER_EVAL_RESULT = 17, /**< eval result */
|
||||||
JERRY_DEBUGGER_EVAL_ERROR_END = 18, /**< last part of eval result when an error is occured */
|
JERRY_DEBUGGER_EVAL_RESULT_END = 18, /**< last part of eval result */
|
||||||
|
JERRY_DEBUGGER_EVAL_ERROR = 19, /**< eval result when an error is occured */
|
||||||
|
JERRY_DEBUGGER_EVAL_ERROR_END = 20, /**< last part of eval result when an error is occured */
|
||||||
|
|
||||||
/* Messages sent by the client to server. */
|
/* Messages sent by the client to server. */
|
||||||
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */
|
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */
|
||||||
|
|||||||
+1
-1
@@ -331,7 +331,7 @@ jerry_parse_named_resource (const jerry_char_t *name_p, /**< name (usually a fil
|
|||||||
#ifdef JERRY_DEBUGGER
|
#ifdef JERRY_DEBUGGER
|
||||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||||
{
|
{
|
||||||
jerry_debugger_send_string (JERRY_DEBUGGER_RESOURCE_NAME, name_p, name_length);
|
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME, name_p, name_length);
|
||||||
}
|
}
|
||||||
#else /* JERRY_DEBUGGER */
|
#else /* JERRY_DEBUGGER */
|
||||||
JERRY_UNUSED (name_p);
|
JERRY_UNUSED (name_p);
|
||||||
|
|||||||
@@ -2371,6 +2371,14 @@ parser_parse_script (const uint8_t *source_p, /**< source code */
|
|||||||
{
|
{
|
||||||
#ifdef JERRY_JS_PARSER
|
#ifdef JERRY_JS_PARSER
|
||||||
parser_error_location_t parser_error;
|
parser_error_location_t parser_error;
|
||||||
|
|
||||||
|
#ifdef JERRY_DEBUGGER
|
||||||
|
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||||
|
{
|
||||||
|
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE, source_p, size);
|
||||||
|
}
|
||||||
|
#endif /* JERRY_DEBUGGER */
|
||||||
|
|
||||||
*bytecode_data_p = parser_parse_source (source_p, size, is_strict, &parser_error);
|
*bytecode_data_p = parser_parse_source (source_p, size, is_strict, &parser_error);
|
||||||
|
|
||||||
if (!*bytecode_data_p)
|
if (!*bytecode_data_p)
|
||||||
|
|||||||
@@ -34,18 +34,20 @@ var JERRY_DEBUGGER_BYTE_CODE_CP = 3;
|
|||||||
var JERRY_DEBUGGER_PARSE_FUNCTION = 4;
|
var JERRY_DEBUGGER_PARSE_FUNCTION = 4;
|
||||||
var JERRY_DEBUGGER_BREAKPOINT_LIST = 5;
|
var JERRY_DEBUGGER_BREAKPOINT_LIST = 5;
|
||||||
var JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6;
|
var JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6;
|
||||||
var JERRY_DEBUGGER_RESOURCE_NAME = 7;
|
var JERRY_DEBUGGER_SOURCE_CODE = 7;
|
||||||
var JERRY_DEBUGGER_RESOURCE_NAME_END = 8;
|
var JERRY_DEBUGGER_SOURCE_CODE_END = 8;
|
||||||
var JERRY_DEBUGGER_FUNCTION_NAME = 9;
|
var JERRY_DEBUGGER_SOURCE_CODE_NAME = 9;
|
||||||
var JERRY_DEBUGGER_FUNCTION_NAME_END = 10;
|
var JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10;
|
||||||
var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 11;
|
var JERRY_DEBUGGER_FUNCTION_NAME = 11;
|
||||||
var JERRY_DEBUGGER_BREAKPOINT_HIT = 12;
|
var JERRY_DEBUGGER_FUNCTION_NAME_END = 12;
|
||||||
var JERRY_DEBUGGER_BACKTRACE = 13;
|
var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13;
|
||||||
var JERRY_DEBUGGER_BACKTRACE_END = 14;
|
var JERRY_DEBUGGER_BREAKPOINT_HIT = 14;
|
||||||
var JERRY_DEBUGGER_EVAL_RESULT = 15;
|
var JERRY_DEBUGGER_BACKTRACE = 15;
|
||||||
var JERRY_DEBUGGER_EVAL_RESULT_END = 16;
|
var JERRY_DEBUGGER_BACKTRACE_END = 16;
|
||||||
var JERRY_DEBUGGER_EVAL_ERROR = 17;
|
var JERRY_DEBUGGER_EVAL_RESULT = 17;
|
||||||
var JERRY_DEBUGGER_EVAL_ERROR_END = 18;
|
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_FREE_BYTE_CODE_CP = 1;
|
||||||
var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
|
var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
|
||||||
@@ -81,6 +83,7 @@ function DebuggerClient(address)
|
|||||||
var littleEndian = true;
|
var littleEndian = true;
|
||||||
var functions = { };
|
var functions = { };
|
||||||
var lineList = new Multimap();
|
var lineList = new Multimap();
|
||||||
|
var lastBreakpointHit = null;
|
||||||
var activeBreakpoints = { };
|
var activeBreakpoints = { };
|
||||||
var nextBreakpointIndex = 1;
|
var nextBreakpointIndex = 1;
|
||||||
var backtraceFrame = 0;
|
var backtraceFrame = 0;
|
||||||
@@ -239,7 +242,7 @@ function DebuggerClient(address)
|
|||||||
{
|
{
|
||||||
var name = breakpoint.func.name;
|
var name = breakpoint.func.name;
|
||||||
|
|
||||||
var result = breakpoint.func.resource;
|
var result = breakpoint.func.sourceName;
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -465,9 +468,12 @@ function DebuggerClient(address)
|
|||||||
|
|
||||||
function ParseSource()
|
function ParseSource()
|
||||||
{
|
{
|
||||||
var resourceName = null;
|
var source = "";
|
||||||
|
var sourceData = null;
|
||||||
|
var sourceName = "";
|
||||||
|
var sourceNameData = null;
|
||||||
var functionName = null;
|
var functionName = null;
|
||||||
var stack = [ { name: '', lines: [], offsets: [] } ];
|
var stack = [ { name: "", source: "", lines: [], offsets: [] } ];
|
||||||
var newFunctions = [ ];
|
var newFunctions = [ ];
|
||||||
|
|
||||||
this.receive = function(message)
|
this.receive = function(message)
|
||||||
@@ -481,19 +487,26 @@ function DebuggerClient(address)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case JERRY_DEBUGGER_RESOURCE_NAME:
|
case JERRY_DEBUGGER_SOURCE_CODE:
|
||||||
case JERRY_DEBUGGER_RESOURCE_NAME_END:
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@@ -507,16 +520,11 @@ function DebuggerClient(address)
|
|||||||
|
|
||||||
case JERRY_DEBUGGER_PARSE_FUNCTION:
|
case JERRY_DEBUGGER_PARSE_FUNCTION:
|
||||||
{
|
{
|
||||||
if (resourceName == null)
|
stack.push({ name: cesu8ToString(functionName),
|
||||||
{
|
source: source,
|
||||||
resourceName = "";
|
sourceName: sourceName,
|
||||||
}
|
lines: [],
|
||||||
else if ((typeof resourceName) != "string")
|
offsets: [] });
|
||||||
{
|
|
||||||
abortConnection("unexpected message.");
|
|
||||||
}
|
|
||||||
|
|
||||||
stack.push({ name: cesu8ToString(functionName), resource: resourceName, lines: [], offsets: [] });
|
|
||||||
functionName = null;
|
functionName = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -575,7 +583,8 @@ function DebuggerClient(address)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
func.resource = resourceName;
|
func.source = source;
|
||||||
|
func.sourceName = sourceName;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,8 +653,10 @@ function DebuggerClient(address)
|
|||||||
case JERRY_DEBUGGER_BYTE_CODE_CP:
|
case JERRY_DEBUGGER_BYTE_CODE_CP:
|
||||||
case JERRY_DEBUGGER_PARSE_FUNCTION:
|
case JERRY_DEBUGGER_PARSE_FUNCTION:
|
||||||
case JERRY_DEBUGGER_BREAKPOINT_LIST:
|
case JERRY_DEBUGGER_BREAKPOINT_LIST:
|
||||||
case JERRY_DEBUGGER_RESOURCE_NAME:
|
case JERRY_DEBUGGER_SOURCE_CODE:
|
||||||
case JERRY_DEBUGGER_RESOURCE_NAME_END:
|
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:
|
||||||
case JERRY_DEBUGGER_FUNCTION_NAME_END:
|
case JERRY_DEBUGGER_FUNCTION_NAME_END:
|
||||||
{
|
{
|
||||||
@@ -686,8 +697,9 @@ function DebuggerClient(address)
|
|||||||
|
|
||||||
breakpoint = functions[breakpoint[0]].offsets[breakpoint[1]];
|
breakpoint = functions[breakpoint[0]].offsets[breakpoint[1]];
|
||||||
|
|
||||||
breakpointIndex = "";
|
lastBreakpointHit = breakpoint;
|
||||||
|
|
||||||
|
breakpointIndex = "";
|
||||||
if (breakpoint.activeIndex >= 0)
|
if (breakpoint.activeIndex >= 0)
|
||||||
{
|
{
|
||||||
breakpointIndex = "breakpoint:" + breakpoint.activeIndex + " ";
|
breakpointIndex = "breakpoint:" + breakpoint.activeIndex + " ";
|
||||||
@@ -800,11 +812,11 @@ function DebuggerClient(address)
|
|||||||
for (var i = 0; i < functionList.length; ++i)
|
for (var i = 0; i < functionList.length; ++i)
|
||||||
{
|
{
|
||||||
var func = functionList[i];
|
var func = functionList[i];
|
||||||
var resource = func.resource;
|
var sourceName = func.sourceName;
|
||||||
|
|
||||||
if (resource == line[1]
|
if (sourceName == line[1]
|
||||||
|| resource.endsWith("/" + line[1])
|
|| sourceName.endsWith("/" + line[1])
|
||||||
|| resource.endsWith("\\" + line[1]))
|
|| sourceName.endsWith("\\" + line[1]))
|
||||||
{
|
{
|
||||||
insertBreakpoint(func.lines[line[2]]);
|
insertBreakpoint(func.lines[line[2]]);
|
||||||
}
|
}
|
||||||
@@ -894,19 +906,27 @@ function DebuggerClient(address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.printSource = function()
|
||||||
|
{
|
||||||
|
if (lastBreakpointHit)
|
||||||
|
{
|
||||||
|
appendLog(lastBreakpointHit.func.source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.dump = function()
|
this.dump = function()
|
||||||
{
|
{
|
||||||
for (var i in functions)
|
for (var i in functions)
|
||||||
{
|
{
|
||||||
var func = functions[i];
|
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)
|
for (var j in func.lines)
|
||||||
{
|
{
|
||||||
@@ -958,6 +978,7 @@ function debuggerCommand(event)
|
|||||||
" next|n - connect to server\n" +
|
" next|n - connect to server\n" +
|
||||||
" eval|e - evaluate expression\n" +
|
" eval|e - evaluate expression\n" +
|
||||||
" backtrace|bt <max-depth> - get backtrace\n" +
|
" backtrace|bt <max-depth> - get backtrace\n" +
|
||||||
|
" src - print current source code\n" +
|
||||||
" dump - dump all breakpoint data");
|
" dump - dump all breakpoint data");
|
||||||
|
|
||||||
commandBox.value = "";
|
commandBox.value = "";
|
||||||
@@ -1063,6 +1084,10 @@ function debuggerCommand(event)
|
|||||||
debuggerObj.encodeMessage("BI", [ JERRY_DEBUGGER_GET_BACKTRACE, max_depth ]);
|
debuggerObj.encodeMessage("BI", [ JERRY_DEBUGGER_GET_BACKTRACE, max_depth ]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "src":
|
||||||
|
debuggerObj.printSource();
|
||||||
|
break;
|
||||||
|
|
||||||
case "list":
|
case "list":
|
||||||
debuggerObj.listBreakpoints();
|
debuggerObj.listBreakpoints();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -31,18 +31,20 @@ JERRY_DEBUGGER_BYTE_CODE_CP = 3
|
|||||||
JERRY_DEBUGGER_PARSE_FUNCTION = 4
|
JERRY_DEBUGGER_PARSE_FUNCTION = 4
|
||||||
JERRY_DEBUGGER_BREAKPOINT_LIST = 5
|
JERRY_DEBUGGER_BREAKPOINT_LIST = 5
|
||||||
JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6
|
JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME = 7
|
JERRY_DEBUGGER_SOURCE_CODE = 7
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME_END = 8
|
JERRY_DEBUGGER_SOURCE_CODE_END = 8
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME = 9
|
JERRY_DEBUGGER_SOURCE_CODE_NAME = 9
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME_END = 10
|
JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10
|
||||||
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 11
|
JERRY_DEBUGGER_FUNCTION_NAME = 11
|
||||||
JERRY_DEBUGGER_BREAKPOINT_HIT = 12
|
JERRY_DEBUGGER_FUNCTION_NAME_END = 12
|
||||||
JERRY_DEBUGGER_BACKTRACE = 13
|
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13
|
||||||
JERRY_DEBUGGER_BACKTRACE_END = 14
|
JERRY_DEBUGGER_BREAKPOINT_HIT = 14
|
||||||
JERRY_DEBUGGER_EVAL_RESULT = 15
|
JERRY_DEBUGGER_BACKTRACE = 15
|
||||||
JERRY_DEBUGGER_EVAL_RESULT_END = 16
|
JERRY_DEBUGGER_BACKTRACE_END = 16
|
||||||
JERRY_DEBUGGER_EVAL_ERROR = 17
|
JERRY_DEBUGGER_EVAL_RESULT = 17
|
||||||
JERRY_DEBUGGER_EVAL_ERROR_END = 18
|
JERRY_DEBUGGER_EVAL_RESULT_END = 18
|
||||||
|
JERRY_DEBUGGER_EVAL_ERROR = 19
|
||||||
|
JERRY_DEBUGGER_EVAL_ERROR_END = 20
|
||||||
|
|
||||||
# Messages sent by the client to server.
|
# Messages sent by the client to server.
|
||||||
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
|
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
|
||||||
@@ -84,7 +86,7 @@ class JerryBreakpoint(object):
|
|||||||
self.active_index = -1
|
self.active_index = -1
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
result = self.function.source
|
result = self.function.source_name
|
||||||
|
|
||||||
if result == "":
|
if result == "":
|
||||||
result = "<unknown>"
|
result = "<unknown>"
|
||||||
@@ -102,15 +104,16 @@ class JerryBreakpoint(object):
|
|||||||
|
|
||||||
class JerryFunction(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.byte_code_cp = byte_code_cp
|
||||||
self.source = source
|
self.source = source
|
||||||
|
self.source_name = source_name
|
||||||
self.name = name
|
self.name = name
|
||||||
self.lines = {}
|
self.lines = {}
|
||||||
self.offsets = {}
|
self.offsets = {}
|
||||||
self.first_line = -1
|
self.first_line = -1
|
||||||
|
|
||||||
if len > 0:
|
if lines:
|
||||||
self.first_line = lines[0]
|
self.first_line = lines[0]
|
||||||
|
|
||||||
for i in range(len(lines)):
|
for i in range(len(lines)):
|
||||||
@@ -121,8 +124,8 @@ class JerryFunction(object):
|
|||||||
self.offsets[offset] = breakpoint
|
self.offsets[offset] = breakpoint
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
result = ("Function(byte_code_cp:0x%x, source:\"%s\", name:\"%s\", { "
|
result = ("Function(byte_code_cp:0x%x, source_name:\"%s\", name:\"%s\", { "
|
||||||
% (self.byte_code_cp, self.source, self.name))
|
% (self.byte_code_cp, self.source_name, self.name))
|
||||||
|
|
||||||
result += ','.join([str(breakpoint) for breakpoint in self.lines.values()])
|
result += ','.join([str(breakpoint) for breakpoint in self.lines.values()])
|
||||||
|
|
||||||
@@ -248,6 +251,11 @@ class DebuggerPrompt(Cmd):
|
|||||||
""" Get backtrace data from debugger """
|
""" Get backtrace data from debugger """
|
||||||
self.exec_backtrace(args)
|
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):
|
def do_dump(self, args):
|
||||||
""" Dump all of the debugger data """
|
""" Dump all of the debugger data """
|
||||||
pprint(self.debugger.function_list)
|
pprint(self.debugger.function_list)
|
||||||
@@ -348,6 +356,7 @@ class JerryDebugger(object):
|
|||||||
|
|
||||||
self.message_data = b""
|
self.message_data = b""
|
||||||
self.function_list = {}
|
self.function_list = {}
|
||||||
|
self.last_breakpoint_hit = None
|
||||||
self.next_breakpoint_index = 0
|
self.next_breakpoint_index = 0
|
||||||
self.active_breakpoint_list = {}
|
self.active_breakpoint_list = {}
|
||||||
self.line_list = Multimap()
|
self.line_list = Multimap()
|
||||||
@@ -480,7 +489,8 @@ class JerryDebugger(object):
|
|||||||
|
|
||||||
|
|
||||||
def parse_source(debugger, data):
|
def parse_source(debugger, data):
|
||||||
source_name = ""
|
source_code = ""
|
||||||
|
source_code_name = ""
|
||||||
function_name = ""
|
function_name = ""
|
||||||
stack = [{"lines": [], "offsets": [], "name": ""}]
|
stack = [{"lines": [], "offsets": [], "name": ""}]
|
||||||
new_function_list = {}
|
new_function_list = {}
|
||||||
@@ -498,15 +508,22 @@ def parse_source(debugger, data):
|
|||||||
logging.error("Parser error!")
|
logging.error("Parser error!")
|
||||||
return
|
return
|
||||||
|
|
||||||
if buffer_type in [JERRY_DEBUGGER_RESOURCE_NAME, JERRY_DEBUGGER_RESOURCE_NAME_END]:
|
elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]:
|
||||||
source_name += data[3:]
|
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]:
|
elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]:
|
||||||
function_name += data[3:]
|
function_name += data[3:]
|
||||||
|
|
||||||
elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION:
|
elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION:
|
||||||
logging.debug("Source name: %s, function name: %s" % (source_name, function_name))
|
logging.debug("Source name: %s, function name: %s" % (source_code_name, function_name))
|
||||||
stack.append({"name": function_name, "source": source_name, "lines": [], "offsets": []})
|
stack.append({ "source": source_code,
|
||||||
|
"source_name": source_code_name,
|
||||||
|
"name": function_name,
|
||||||
|
"lines": [],
|
||||||
|
"offsets": []})
|
||||||
function_name = ""
|
function_name = ""
|
||||||
|
|
||||||
elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]:
|
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.
|
# We know the last item in the list is the general byte code.
|
||||||
if len(stack) == 0:
|
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,
|
function = JerryFunction(byte_code_cp,
|
||||||
func_desc["source"],
|
func_desc["source"],
|
||||||
|
func_desc["source_name"],
|
||||||
func_desc["name"],
|
func_desc["name"],
|
||||||
func_desc["lines"],
|
func_desc["lines"],
|
||||||
func_desc["offsets"])
|
func_desc["offsets"])
|
||||||
@@ -604,14 +623,14 @@ def set_breakpoint(debugger, string):
|
|||||||
found = False
|
found = False
|
||||||
|
|
||||||
if line:
|
if line:
|
||||||
source = line.group(1)
|
source_name = line.group(1)
|
||||||
line = int(line.group(2))
|
line = int(line.group(2))
|
||||||
|
|
||||||
for breakpoint in debugger.line_list.get(line):
|
for breakpoint in debugger.line_list.get(line):
|
||||||
func_source = breakpoint.function.source
|
func_source = breakpoint.function.source_name
|
||||||
if (source == func_source or
|
if (source_name == func_source or
|
||||||
func_source.endswith("/" + source) or
|
func_source.endswith("/" + source_name) or
|
||||||
func_source.endswith("\\" + source)):
|
func_source.endswith("\\" + source_name)):
|
||||||
|
|
||||||
enable_breakpoint(debugger, breakpoint)
|
enable_breakpoint(debugger, breakpoint)
|
||||||
found = True
|
found = True
|
||||||
@@ -656,8 +675,10 @@ def main():
|
|||||||
JERRY_DEBUGGER_BYTE_CODE_CP,
|
JERRY_DEBUGGER_BYTE_CODE_CP,
|
||||||
JERRY_DEBUGGER_PARSE_FUNCTION,
|
JERRY_DEBUGGER_PARSE_FUNCTION,
|
||||||
JERRY_DEBUGGER_BREAKPOINT_LIST,
|
JERRY_DEBUGGER_BREAKPOINT_LIST,
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME,
|
JERRY_DEBUGGER_SOURCE_CODE,
|
||||||
JERRY_DEBUGGER_RESOURCE_NAME_END,
|
JERRY_DEBUGGER_SOURCE_CODE_END,
|
||||||
|
JERRY_DEBUGGER_SOURCE_CODE_NAME,
|
||||||
|
JERRY_DEBUGGER_SOURCE_CODE_NAME_END,
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME,
|
JERRY_DEBUGGER_FUNCTION_NAME,
|
||||||
JERRY_DEBUGGER_FUNCTION_NAME_END]:
|
JERRY_DEBUGGER_FUNCTION_NAME_END]:
|
||||||
parse_source(debugger, data)
|
parse_source(debugger, data)
|
||||||
@@ -671,6 +692,8 @@ def main():
|
|||||||
function = debugger.function_list[breakpoint_data[0]]
|
function = debugger.function_list[breakpoint_data[0]]
|
||||||
breakpoint = function.offsets[breakpoint_data[1]]
|
breakpoint = function.offsets[breakpoint_data[1]]
|
||||||
|
|
||||||
|
debugger.last_breakpoint_hit = breakpoint
|
||||||
|
|
||||||
breakpoint_index = ""
|
breakpoint_index = ""
|
||||||
if breakpoint.active_index >= 0:
|
if breakpoint.active_index >= 0:
|
||||||
breakpoint_index = " breakpoint:%d" % (breakpoint.active_index)
|
breakpoint_index = " breakpoint:%d" % (breakpoint.active_index)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Connecting to: localhost:5001
|
Connecting to: localhost:5001
|
||||||
Stopped at tests/debugger/do_dump.js:15
|
Stopped at tests/debugger/do_dump.js:15
|
||||||
(jerry-debugger) {68: Function(byte_code_cp:0x44, source:"tests/debugger/do_dump.js", name:"f4", { Breakpoint(line:32, offset:17, active_index:-1),Breakpoint(line:31, offset:16, active_index:-1) }),
|
(jerry-debugger) {68: Function(byte_code_cp:0x44, source_name:"tests/debugger/do_dump.js", name:"f4", { Breakpoint(line:32, offset:17, active_index:-1),Breakpoint(line:31, offset:16, active_index:-1) }),
|
||||||
79: Function(byte_code_cp:0x4f, source:"tests/debugger/do_dump.js", name:"f1", { Breakpoint(line:17, offset:21, active_index:-1),Breakpoint(line:27, offset:22, active_index:-1) }),
|
79: Function(byte_code_cp:0x4f, source_name:"tests/debugger/do_dump.js", name:"f1", { Breakpoint(line:17, offset:21, active_index:-1),Breakpoint(line:27, offset:22, active_index:-1) }),
|
||||||
102: Function(byte_code_cp:0x66, source:"tests/debugger/do_dump.js", name:"f2", { Breakpoint(line:19, offset:14, active_index:-1),Breakpoint(line:21, offset:15, active_index:-1) }),
|
102: Function(byte_code_cp:0x66, source_name:"tests/debugger/do_dump.js", name:"f2", { Breakpoint(line:19, offset:14, active_index:-1),Breakpoint(line:21, offset:15, active_index:-1) }),
|
||||||
105: Function(byte_code_cp:0x69, source:"tests/debugger/do_dump.js", name:"foo", { Breakpoint(line:35, offset:22, active_index:-1),Breakpoint(line:37, offset:23, active_index:-1),Breakpoint(line:38, offset:28, active_index:-1),Breakpoint(line:39, offset:33, active_index:-1) }),
|
105: Function(byte_code_cp:0x69, source_name:"tests/debugger/do_dump.js", name:"foo", { Breakpoint(line:35, offset:22, active_index:-1),Breakpoint(line:37, offset:23, active_index:-1),Breakpoint(line:38, offset:28, active_index:-1),Breakpoint(line:39, offset:33, active_index:-1) }),
|
||||||
125: Function(byte_code_cp:0x7d, source:"tests/debugger/do_dump.js", name:"f3", { Breakpoint(line:22, offset:25, active_index:-1),Breakpoint(line:23, offset:30, active_index:-1) }),
|
125: Function(byte_code_cp:0x7d, source_name:"tests/debugger/do_dump.js", name:"f3", { Breakpoint(line:22, offset:25, active_index:-1),Breakpoint(line:23, offset:30, active_index:-1) }),
|
||||||
131: Function(byte_code_cp:0x83, source:"tests/debugger/do_dump.js", name:"", { Breakpoint(line:57, offset:63, active_index:-1),Breakpoint(line:42, offset:54, active_index:-1),Breakpoint(line:43, offset:59, active_index:-1),Breakpoint(line:60, offset:68, active_index:-1),Breakpoint(line:15, offset:49, active_index:-1) }),
|
131: Function(byte_code_cp:0x83, source_name:"tests/debugger/do_dump.js", name:"", { Breakpoint(line:57, offset:63, active_index:-1),Breakpoint(line:42, offset:54, active_index:-1),Breakpoint(line:43, offset:59, active_index:-1),Breakpoint(line:60, offset:68, active_index:-1),Breakpoint(line:15, offset:49, active_index:-1) }),
|
||||||
154: Function(byte_code_cp:0x9a, source:"tests/debugger/do_dump.js", name:"test", { Breakpoint(line:45, offset:28, active_index:-1),Breakpoint(line:47, offset:29, active_index:-1),Breakpoint(line:48, offset:34, active_index:-1),Breakpoint(line:49, offset:38, active_index:-1),Breakpoint(line:50, offset:43, active_index:-1),Breakpoint(line:51, offset:48, active_index:-1),Breakpoint(line:52, offset:54, active_index:-1),Breakpoint(line:53, offset:58, active_index:-1) })}
|
154: Function(byte_code_cp:0x9a, source_name:"tests/debugger/do_dump.js", name:"test", { Breakpoint(line:45, offset:28, active_index:-1),Breakpoint(line:47, offset:29, active_index:-1),Breakpoint(line:48, offset:34, active_index:-1),Breakpoint(line:49, offset:38, active_index:-1),Breakpoint(line:50, offset:43, active_index:-1),Breakpoint(line:51, offset:48, active_index:-1),Breakpoint(line:52, offset:54, active_index:-1),Breakpoint(line:53, offset:58, active_index:-1) })}
|
||||||
(jerry-debugger) Connection closed.
|
(jerry-debugger) Connection closed.
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
b f
|
||||||
|
n
|
||||||
|
n
|
||||||
|
n
|
||||||
|
s
|
||||||
|
src
|
||||||
|
n
|
||||||
|
b f
|
||||||
|
c
|
||||||
|
src
|
||||||
|
c
|
||||||
|
src
|
||||||
|
c
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
Connecting to: localhost:5001
|
||||||
|
Stopped at tests/debugger/do_src.js:19
|
||||||
|
(jerry-debugger) Breakpoint 1 at tests/debugger/do_src.js:15 (in f)
|
||||||
|
(jerry-debugger) Stopped at breakpoint:1 tests/debugger/do_src.js:15 (in f)
|
||||||
|
(jerry-debugger) Stopped at tests/debugger/do_src.js:16 (in f)
|
||||||
|
(jerry-debugger) Stopped at tests/debugger/do_src.js:20
|
||||||
|
(jerry-debugger) Stopped at <unknown>:1
|
||||||
|
(jerry-debugger) f = function f() {
|
||||||
|
print('F2') }
|
||||||
|
(jerry-debugger) Stopped at tests/debugger/do_src.js:21
|
||||||
|
(jerry-debugger) Breakpoint 2 at <unknown>:2 (in f)
|
||||||
|
Breakpoint 1 at tests/debugger/do_src.js:15 (in f)
|
||||||
|
(jerry-debugger) Stopped at breakpoint:2 <unknown>:2 (in f)
|
||||||
|
(jerry-debugger) f = function f() {
|
||||||
|
print('F2') }
|
||||||
|
(jerry-debugger) Stopped at breakpoint:2 <unknown>:2 (in f)
|
||||||
|
(jerry-debugger) f = function f() {
|
||||||
|
print('F2') }
|
||||||
|
(jerry-debugger) Connection closed.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
function f() {
|
||||||
|
print("F1");
|
||||||
|
}
|
||||||
|
|
||||||
|
f();
|
||||||
|
eval("f = function f() {\nprint('F2') }");
|
||||||
|
f();
|
||||||
|
f();
|
||||||
Reference in New Issue
Block a user