diff --git a/jerry-core/debugger/jerry-debugger-ws.c b/jerry-core/debugger/jerry-debugger-ws.c
index ba5bda9913..efe433afdc 100644
--- a/jerry-core/debugger/jerry-debugger-ws.c
+++ b/jerry-core/debugger/jerry-debugger-ws.c
@@ -69,10 +69,7 @@ jerry_debugger_close_connection_tcp (bool log_error) /**< log error */
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
- uint8_t debugger_flags = JERRY_CONTEXT (debugger_flags);
- debugger_flags = (uint8_t) (debugger_flags & ~(JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_VM_STOP));
- debugger_flags = (uint8_t) (debugger_flags | JERRY_DEBUGGER_VM_IGNORE);
- JERRY_CONTEXT (debugger_flags) = debugger_flags;
+ JERRY_CONTEXT (debugger_flags) = (uint8_t) JERRY_DEBUGGER_VM_IGNORE;
if (log_error)
{
diff --git a/jerry-core/debugger/jerry-debugger.c b/jerry-core/debugger/jerry-debugger.c
index 4845615df1..8d6d7bab30 100644
--- a/jerry-core/debugger/jerry-debugger.c
+++ b/jerry-core/debugger/jerry-debugger.c
@@ -391,6 +391,28 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
return true;
}
+ case JERRY_DEBUGGER_EXCEPTION_CONFIG:
+ {
+ JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t);
+ JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_exception_config_t, exception_config_p);
+
+ uint8_t debugger_flags = JERRY_CONTEXT (debugger_flags);
+
+ if (exception_config_p->enable == 0)
+ {
+ debugger_flags = (uint8_t) (debugger_flags | JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
+ jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception disabled\n");
+ }
+ else
+ {
+ debugger_flags = (uint8_t) (debugger_flags & ~JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
+ jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception enabled\n");
+ }
+
+ JERRY_CONTEXT (debugger_flags) = debugger_flags;
+ return true;
+ }
+
case JERRY_DEBUGGER_EVAL:
{
if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 1)
@@ -450,7 +472,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
* Tell the client that a breakpoint has been hit and wait for further debugger commands.
*/
void
-jerry_debugger_breakpoint_hit (void)
+jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
@@ -458,7 +480,7 @@ jerry_debugger_breakpoint_hit (void)
JERRY_DEBUGGER_INIT_SEND_MESSAGE (breakpoint_hit_p);
JERRY_DEBUGGER_SET_SEND_MESSAGE_SIZE_FROM_TYPE (breakpoint_hit_p, jerry_debugger_send_breakpoint_hit_t);
- breakpoint_hit_p->type = (uint8_t) JERRY_DEBUGGER_BREAKPOINT_HIT;
+ breakpoint_hit_p->type = message_type;
vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
diff --git a/jerry-core/debugger/jerry-debugger.h b/jerry-core/debugger/jerry-debugger.h
index 5a87d8a9f4..88d0f5c2b1 100644
--- a/jerry-core/debugger/jerry-debugger.h
+++ b/jerry-core/debugger/jerry-debugger.h
@@ -77,6 +77,7 @@ typedef enum
JERRY_DEBUGGER_BREAKPOINT_MODE = 1u << 1, /**< debugger waiting at a breakpoint */
JERRY_DEBUGGER_VM_STOP = 1u << 2, /**< stop at the next breakpoint regardless it is enabled */
JERRY_DEBUGGER_VM_IGNORE = 1u << 3, /**< ignore all breakpoints */
+ JERRY_DEBUGGER_VM_IGNORE_EXCEPTION = 1u << 4, /**< debugger stop at an exception */
} jerry_debugger_flags_t;
/**
@@ -99,29 +100,31 @@ typedef enum
JERRY_DEBUGGER_FUNCTION_NAME_END = 12, /**< function name last fragment */
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13, /**< invalidate byte code compressed pointer */
JERRY_DEBUGGER_BREAKPOINT_HIT = 14, /**< notify breakpoint hit */
- JERRY_DEBUGGER_BACKTRACE = 15, /**< backtrace data */
- JERRY_DEBUGGER_BACKTRACE_END = 16, /**< last backtrace data */
- JERRY_DEBUGGER_EVAL_RESULT = 17, /**< eval result */
- 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 */
+ JERRY_DEBUGGER_EXCEPTION_HIT = 15, /**< notify exception hit */
+ JERRY_DEBUGGER_BACKTRACE = 16, /**< backtrace data */
+ JERRY_DEBUGGER_BACKTRACE_END = 17, /**< last backtrace data */
+ JERRY_DEBUGGER_EVAL_RESULT = 18, /**< eval result */
+ JERRY_DEBUGGER_EVAL_RESULT_END = 19, /**< last part of eval result */
+ JERRY_DEBUGGER_EVAL_ERROR = 20, /**< eval result when an error is occured */
+ JERRY_DEBUGGER_EVAL_ERROR_END = 21, /**< last part of eval result when an error is occured */
/* Messages sent by the client to server. */
/* The following messages are accepted in both run and breakpoint modes. */
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */
JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2, /**< update breakpoint status */
- JERRY_DEBUGGER_STOP = 3, /**< stop execution */
+ JERRY_DEBUGGER_EXCEPTION_CONFIG = 3, /**< exception handler config */
+ JERRY_DEBUGGER_STOP = 4, /**< stop execution */
/* The following messages are only available in breakpoint
* mode and they switch the engine to run mode. */
- JERRY_DEBUGGER_CONTINUE = 4, /**< continue execution */
- JERRY_DEBUGGER_STEP = 5, /**< next breakpoint, step into functions */
- JERRY_DEBUGGER_NEXT = 6, /**< next breakpoint in the same context */
+ JERRY_DEBUGGER_CONTINUE = 5, /**< continue execution */
+ JERRY_DEBUGGER_STEP = 6, /**< next breakpoint, step into functions */
+ JERRY_DEBUGGER_NEXT = 7, /**< next breakpoint in the same context */
/* The following messages are only available in breakpoint
* mode and this mode is kept after the message is processed. */
- JERRY_DEBUGGER_GET_BACKTRACE = 7, /**< get backtrace */
- JERRY_DEBUGGER_EVAL = 8, /**< first message of evaluating a string */
- JERRY_DEBUGGER_EVAL_PART = 9, /**< next message of evaluating a string */
+ JERRY_DEBUGGER_GET_BACKTRACE = 8, /**< get backtrace */
+ JERRY_DEBUGGER_EVAL = 9, /**< first message of evaluating a string */
+ JERRY_DEBUGGER_EVAL_PART = 10, /**< next message of evaluating a string */
} jerry_debugger_header_type_t;
/**
@@ -243,6 +246,12 @@ typedef struct
jerry_debugger_frame_t frames[JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t)]; /**< frames */
} jerry_debugger_send_backtrace_t;
+typedef struct
+{
+ uint8_t type; /**< type of the message */
+ uint8_t enable; /**< non-zero: enable stop at exception */
+} jerry_debugger_receive_exception_config_t;
+
/**
* Incoming message: get backtrace.
*/
@@ -282,7 +291,7 @@ void jerry_debugger_free_unreferenced_byte_code (void);
bool jerry_debugger_process_message (uint8_t *recv_buffer_p, uint32_t message_size,
bool *resume_exec_p, uint8_t *expected_message_p, void **message_data_p);
-void jerry_debugger_breakpoint_hit (void);
+void jerry_debugger_breakpoint_hit (uint8_t message_type);
void jerry_debugger_send_type (jerry_debugger_header_type_t type);
bool jerry_debugger_send_configuration (uint8_t max_message_size);
diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c
index 401369445e..63090fc2b6 100644
--- a/jerry-core/vm/vm.c
+++ b/jerry-core/vm/vm.c
@@ -2338,7 +2338,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
frame_ctx_p->byte_code_p = byte_code_start_p;
- jerry_debugger_breakpoint_hit ();
+ jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
#endif /* JERRY_DEBUGGER */
continue;
}
@@ -2360,7 +2360,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
&& (JERRY_CONTEXT (debugger_stop_context) == NULL
|| JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p)))
{
- jerry_debugger_breakpoint_hit ();
+ jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
continue;
}
@@ -2380,7 +2380,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP)
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_stop_context) == NULL);
- jerry_debugger_breakpoint_hit ();
+ jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
}
#endif /* JERRY_DEBUGGER */
continue;
@@ -2515,6 +2515,15 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
stack_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
+#ifdef JERRY_DEBUGGER
+ JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
+
+ if (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
+ && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE_EXCEPTION))
+ {
+ jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_EXCEPTION_HIT);
+ }
+#endif /* JERRY_DEBUGGER */
}
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
diff --git a/jerry-debugger/jerry-client-ws.html b/jerry-debugger/jerry-client-ws.html
index 6d2899e76a..9e0b9e375b 100644
--- a/jerry-debugger/jerry-client-ws.html
+++ b/jerry-debugger/jerry-client-ws.html
@@ -42,22 +42,24 @@
JerryScript HTML (WebSocket) Debugger Client
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_EXCEPTION_HIT = 15;
+var JERRY_DEBUGGER_BACKTRACE = 16;
+var JERRY_DEBUGGER_BACKTRACE_END = 17;
+var JERRY_DEBUGGER_EVAL_RESULT = 18;
+var JERRY_DEBUGGER_EVAL_RESULT_END = 19;
+var JERRY_DEBUGGER_EVAL_ERROR = 20;
+var JERRY_DEBUGGER_EVAL_ERROR_END = 21;
var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1;
var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
-var JERRY_DEBUGGER_STOP = 3;
-var JERRY_DEBUGGER_CONTINUE = 4;
-var JERRY_DEBUGGER_STEP = 5;
-var JERRY_DEBUGGER_NEXT = 6;
-var JERRY_DEBUGGER_GET_BACKTRACE = 7;
-var JERRY_DEBUGGER_EVAL = 8;
-var JERRY_DEBUGGER_EVAL_PART = 9;
+var JERRY_DEBUGGER_EXCEPTION_CONFIG = 3;
+var JERRY_DEBUGGER_STOP = 4;
+var JERRY_DEBUGGER_CONTINUE = 5;
+var JERRY_DEBUGGER_STEP = 6;
+var JERRY_DEBUGGER_NEXT = 7;
+var JERRY_DEBUGGER_GET_BACKTRACE = 8;
+var JERRY_DEBUGGER_EVAL = 9;
+var JERRY_DEBUGGER_EVAL_PART = 10;
var textBox = document.getElementById("log");
var commandBox = document.getElementById("command");
@@ -495,6 +497,41 @@ JerryScript HTML (WebSocket) Debugger Client
socket.send(message);
}
+ function getBreakpoint(breakpointData)
+ {
+ var returnValue = {};
+ var func = functions[breakpointData[0]];
+ var offset = breakpointData[1];
+
+ if (offset in functions)
+ {
+ returnValue.breakpoint = func.offsets[offset];
+ returnValue.at = true;
+ return returnValue;
+ }
+
+ if (offset < functions.firstBreakpointOffset)
+ {
+ returnValue.breakpoint = func.offsets[firstBreakpointOffset];
+ returnValue.at = true;
+ return returnValue;
+ }
+
+ nearest_offset = -1;
+
+ for (var current_offset in func.offsets)
+ {
+ if ((current_offset <= offset) && (current_offset > nearest_offset))
+ {
+ nearest_offset = current_offset;
+ }
+ }
+
+ returnValue.breakpoint = func.offsets[nearest_offset];
+ returnValue.at = false;
+ return returnValue;
+ }
+
this.encodeMessage = encodeMessage;
function ParseSource()
@@ -606,6 +643,7 @@ JerryScript HTML (WebSocket) Debugger Client
offsets = {}
func.firstBreakpointLine = func.lines[0];
+ func.firstBreakpointOffset = func.offsets[0];
for (var i = 0; i < func.lines.length; i++)
{
@@ -729,20 +767,29 @@ JerryScript HTML (WebSocket) Debugger Client
}
case JERRY_DEBUGGER_BREAKPOINT_HIT:
+ case JERRY_DEBUGGER_EXCEPTION_HIT:
{
- var breakpoint = decodeMessage("CI", message, 1);
+ var breakpointData = decodeMessage("CI", message, 1);
+ var breakpointRef = getBreakpoint(breakpointData);
+ var breakpoint = breakpointRef.breakpoint;
- breakpoint = functions[breakpoint[0]].offsets[breakpoint[1]];
+ if (message[0] == JERRY_DEBUGGER_EXCEPTION_HIT)
+ {
+ appendLog("Exception throw detected (to disable automatic stop type exception 0)");
+ }
lastBreakpointHit = breakpoint;
- breakpointIndex = "";
- if (breakpoint.activeIndex >= 0)
+ var breakpointInfo = "";
+ if (breakpoint.offset.activeIndex >= 0)
{
- breakpointIndex = "breakpoint:" + breakpoint.activeIndex + " ";
+ breakpointInfo = " breakpoint:" + breakpoint.offset.activeIndex + " ";
}
- appendLog("Stopped at " + breakpointIndex + breakpointToString(breakpoint));
+ appendLog("Stopped "
+ + (breakpoint.at ? "at " : "around ")
+ + breakpointInfo
+ + breakpointToString(breakpoint));
return;
}
@@ -751,31 +798,14 @@ JerryScript HTML (WebSocket) Debugger Client
{
for (var i = 1; i < message.byteLength; i += cpointerSize + 4)
{
- var breakpoint = decodeMessage("CI", message, i);
- var func = functions[breakpoint[0]];
- var best_offset = -1;
+ var breakpointData = decodeMessage("CI", message, i);
- for (var offset in func.offsets)
- {
- if (offset <= breakpoint[1] && offset > best_offset)
- {
- best_offset = offset;
- }
- }
+ breakpoint = getBreakpoint(breakpointData).breakpoint;
- if (best_offset >= 0)
- {
- breakpoint = func.offsets[best_offset];
- appendLog(" frame " + backtraceFrame + ": " + breakpointToString(breakpoint));
- }
- else if (func.name)
- {
- appendLog(" frame " + backtraceFrame + ": " + func.name + "()");
- }
- else
- {
- appendLog(" frame " + backtraceFrame + ": ()");
- }
+ appendLog(" frame "
+ + backtraceFrame
+ + ": "
+ + breakpointToString(breakpoint));
++backtraceFrame;
}
@@ -873,6 +903,31 @@ JerryScript HTML (WebSocket) Debugger Client
}
}
+ this.sendExceptionConfig = function(enable)
+ {
+ if (enable == "")
+ {
+ appendLog("Argument required");
+ return;
+ }
+
+ if (enable == 1)
+ {
+ appendLog("Stop at exception enabled");
+ }
+ else if (enable == 0)
+ {
+ appendLog("Stop at exception disabled");
+ }
+ else
+ {
+ appendLog("Invalid input. Usage 1: [Enable] or 0: [Disable].");
+ return;
+ }
+
+ encodeMessage("BB", [ JERRY_DEBUGGER_EXCEPTION_CONFIG, enable ]);
+ }
+
this.deleteBreakpoint = function(index)
{
breakpoint = activeBreakpoints[index];
@@ -1178,6 +1233,10 @@ JerryScript HTML (WebSocket) Debugger Client
debuggerObj.sendGetBacktrace(max_depth);
break;
+ case "exception":
+ debuggerObj.sendExceptionConfig(args[2]);
+ break;
+
case "src":
debuggerObj.printSource();
break;
diff --git a/jerry-debugger/jerry-client-ws.py b/jerry-debugger/jerry-client-ws.py
index a465f3c7a4..f6a180cb13 100755
--- a/jerry-debugger/jerry-client-ws.py
+++ b/jerry-debugger/jerry-client-ws.py
@@ -40,23 +40,26 @@
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
+JERRY_DEBUGGER_EXCEPTION_HIT = 15
+JERRY_DEBUGGER_BACKTRACE = 16
+JERRY_DEBUGGER_BACKTRACE_END = 17
+JERRY_DEBUGGER_EVAL_RESULT = 18
+JERRY_DEBUGGER_EVAL_RESULT_END = 19
+JERRY_DEBUGGER_EVAL_ERROR = 20
+JERRY_DEBUGGER_EVAL_ERROR_END = 21
+
# Messages sent by the client to server.
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2
-JERRY_DEBUGGER_STOP = 3
-JERRY_DEBUGGER_CONTINUE = 4
-JERRY_DEBUGGER_STEP = 5
-JERRY_DEBUGGER_NEXT = 6
-JERRY_DEBUGGER_GET_BACKTRACE = 7
-JERRY_DEBUGGER_EVAL = 8
-JERRY_DEBUGGER_EVAL_PART = 9
+JERRY_DEBUGGER_EXCEPTION_CONFIG = 3
+JERRY_DEBUGGER_STOP = 4
+JERRY_DEBUGGER_CONTINUE = 5
+JERRY_DEBUGGER_STEP = 6
+JERRY_DEBUGGER_NEXT = 7
+JERRY_DEBUGGER_GET_BACKTRACE = 8
+JERRY_DEBUGGER_EVAL = 9
+JERRY_DEBUGGER_EVAL_PART = 10
MAX_BUFFER_SIZE = 128
WEBSOCKET_BINARY_FRAME = 2
@@ -122,6 +125,7 @@ def __init__(self, is_func, byte_code_cp, source, source_name, line, column, nam
self.line = line
self.column = column
self.first_breakpoint_line = lines[0]
+ self.first_breakpoint_offset = offsets[0]
for i in range(len(lines)):
line = lines[i]
@@ -332,6 +336,24 @@ def do_eval(self, args):
do_e = do_eval
+ def do_exception(self, args):
+ """ Config the exception handler module """
+ if not args:
+ print("Error: Status expected!")
+ return
+
+ enable = int(args)
+
+ if enable == 1:
+ logging.debug("Stop at exception enabled")
+ elif enable == 0:
+ logging.debug("Stop at exception disabled")
+ else:
+ print("Error: Invalid input! Usage 1: [Enable] or 0: [Disable].")
+ return
+
+ self.debugger.send_exception_config(enable)
+
class Multimap(object):
@@ -475,13 +497,13 @@ def send_breakpoint(self, breakpoint):
self.send_message(message)
def send_bytecode_cp(self, byte_code_cp):
- message = struct.pack(self.byte_order + "BBIB" + self.cp_format,
- WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
- WEBSOCKET_FIN_BIT + 1 + self.cp_size,
- 0,
- JERRY_DEBUGGER_FREE_BYTE_CODE_CP,
- byte_code_cp)
- self.send_message(message)
+ message = struct.pack(self.byte_order + "BBIB" + self.cp_format,
+ WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+ WEBSOCKET_FIN_BIT + 1 + self.cp_size,
+ 0,
+ JERRY_DEBUGGER_FREE_BYTE_CODE_CP,
+ byte_code_cp)
+ self.send_message(message)
def send_command(self, command):
message = struct.pack(self.byte_order + "BBIB",
@@ -491,6 +513,15 @@ def send_command(self, command):
command)
self.send_message(message)
+ def send_exception_config(self, enable):
+ message = struct.pack(self.byte_order + "BBIBB",
+ WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+ WEBSOCKET_FIN_BIT + 1 + 1,
+ 0,
+ JERRY_DEBUGGER_EXCEPTION_CONFIG,
+ enable)
+ self.send_message(message)
+
def get_message(self, blocking):
# Connection was closed
if self.message_data is None:
@@ -698,6 +729,23 @@ def set_breakpoint(debugger, string):
print("Breakpoint not found")
return
+def get_breakpoint(debugger, breakpoint_data):
+ function = debugger.function_list[breakpoint_data[0]]
+ offset = breakpoint_data[1]
+
+ if offset in function.offsets:
+ return (function.offsets[offset], True)
+
+ if offset < function.first_breakpoint_offset:
+ return (function.offsets[function.first_breakpoint_offset], False)
+
+ nearest_offset = -1
+
+ for current_offset in function.offsets:
+ if current_offset <= offset and current_offset > nearest_offset:
+ nearest_offset = current_offset
+
+ return (function.offsets[nearest_offset], False)
def main():
args = arguments_parse()
@@ -747,19 +795,24 @@ def main():
elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
release_function(debugger, data)
- elif buffer_type == JERRY_DEBUGGER_BREAKPOINT_HIT:
+ elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_HIT, JERRY_DEBUGGER_EXCEPTION_HIT]:
breakpoint_data = struct.unpack(debugger.byte_order + debugger.cp_format + debugger.idx_format, data[3:])
- function = debugger.function_list[breakpoint_data[0]]
- breakpoint = function.offsets[breakpoint_data[1]]
+ breakpoint = get_breakpoint(debugger, breakpoint_data)
+ debugger.last_breakpoint_hit = breakpoint[0]
- debugger.last_breakpoint_hit = breakpoint
+ if buffer_type == JERRY_DEBUGGER_EXCEPTION_HIT:
+ print("Exception throw detected (to disable automatic stop type exception 0)")
- breakpoint_index = ""
- if breakpoint.active_index >= 0:
- breakpoint_index = " breakpoint:%d" % (breakpoint.active_index)
+ if breakpoint[1]:
+ breakpoint_info = "at"
+ else:
+ breakpoint_info = "around"
+
+ if breakpoint[0].active_index >= 0:
+ breakpoint_info += " breakpoint:%d" % (breakpoint[0].active_index)
- print("Stopped at%s %s" % (breakpoint_index, breakpoint.to_string()))
+ print("Stopped %s %s" % (breakpoint_info, breakpoint[0].to_string()))
prompt.cmdloop()
if prompt.quit:
@@ -775,20 +828,9 @@ def main():
breakpoint_data = struct.unpack(debugger.byte_order + debugger.cp_format + debugger.idx_format,
data[buffer_pos: buffer_pos + debugger.cp_size + 4])
- function = debugger.function_list[breakpoint_data[0]]
- best_offset = -1
-
- for offset in function.offsets:
- if offset <= breakpoint_data[1] and offset > best_offset:
- best_offset = offset
+ breakpoint = get_breakpoint(debugger, breakpoint_data)
- if best_offset >= 0:
- breakpoint = function.offsets[best_offset]
- print("Frame %d: %s" % (frame_index, breakpoint.to_string()))
- elif function.name:
- print("Frame %d: %s()" % (frame_index, function.name))
- else:
- print("Frame %d: ()" % (frame_index))
+ print("Frame %d: %s" % (frame_index, breakpoint[0].to_string()))
frame_index += 1
buffer_pos += 6
diff --git a/tests/debugger/do_exception.cmd b/tests/debugger/do_exception.cmd
new file mode 100644
index 0000000000..c39e6424f9
--- /dev/null
+++ b/tests/debugger/do_exception.cmd
@@ -0,0 +1,2 @@
+c
+quit
diff --git a/tests/debugger/do_exception.expected b/tests/debugger/do_exception.expected
new file mode 100644
index 0000000000..a7c867ad52
--- /dev/null
+++ b/tests/debugger/do_exception.expected
@@ -0,0 +1,6 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_exception.js:15
+(jerry-debugger) c
+Exception throw detected (to disable automatic stop type exception 0)
+Stopped at tests/debugger/do_exception.js:19 (in foo() at line:17, col:1)
+(jerry-debugger) quit
diff --git a/tests/debugger/do_exception.js b/tests/debugger/do_exception.js
new file mode 100644
index 0000000000..aeb9cecf87
--- /dev/null
+++ b/tests/debugger/do_exception.js
@@ -0,0 +1,25 @@
+// 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.
+
+print("exception handler configuration test")
+
+function foo() {
+ try {
+ b = a / c;
+ } catch (e) {
+ print(e); // pass exception object to err handler
+ }
+}
+
+foo()
diff --git a/tests/debugger/do_help.expected b/tests/debugger/do_help.expected
index 0d8ca5a1fd..c5baf1f0ee 100644
--- a/tests/debugger/do_help.expected
+++ b/tests/debugger/do_help.expected
@@ -4,7 +4,7 @@ Stopped at tests/debugger/do_help.js:15
Documented commands (type help ):
========================================
-b break c delete e help n quit src
-backtrace bt continue dump eval list next s step
+b break c delete e exception list next s step
+backtrace bt continue dump eval help n quit src
(jerry-debugger) quit