Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions jerry-core/debugger/jerry-debugger-ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
26 changes: 24 additions & 2 deletions jerry-core/debugger/jerry-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -450,15 +472,15 @@ 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);

JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_breakpoint_hit_t, breakpoint_hit_p);

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);

Expand Down
37 changes: 23 additions & 14 deletions jerry-core/debugger/jerry-debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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;

/**
Expand Down Expand Up @@ -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 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a boolean value? The description is not obvious to me.

} jerry_debugger_receive_exception_config_t;

/**
* Incoming message: get backtrace.
*/
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 12 additions & 3 deletions jerry-core/vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
143 changes: 101 additions & 42 deletions jerry-debugger/jerry-client-ws.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,24 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
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");
Expand Down Expand Up @@ -495,6 +497,41 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
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()
Expand Down Expand Up @@ -606,6 +643,7 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
offsets = {}

func.firstBreakpointLine = func.lines[0];
func.firstBreakpointOffset = func.offsets[0];

for (var i = 0; i < func.lines.length; i++)
{
Expand Down Expand Up @@ -729,20 +767,29 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
}

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;
}

Expand All @@ -751,31 +798,14 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
{
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 + ": <unknown>()");
}
appendLog(" frame "
+ backtraceFrame
+ ": "
+ breakpointToString(breakpoint));

++backtraceFrame;
}
Expand Down Expand Up @@ -873,6 +903,31 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
}
}

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];
Expand Down Expand Up @@ -1178,6 +1233,10 @@ <h2>JerryScript HTML (WebSocket) Debugger Client</h2>
debuggerObj.sendGetBacktrace(max_depth);
break;

case "exception":
debuggerObj.sendExceptionConfig(args[2]);
break;

case "src":
debuggerObj.printSource();
break;
Expand Down
Loading