Fix inserting pending breakpoints. (#2163)

Before this patch the JS execution is started right after the parsing
is completed. The problem is that some parts of the JS code is executed
before the debugger had any chance to insert pending breakpoints due
to network latency. This patch adds a delay after parsing when at least
one pendding breakpoint is available.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2018-01-23 10:47:47 +01:00 committed by GitHub
parent 40d05cdca2
commit 1c64c1aeb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 271 additions and 147 deletions

View File

@ -43,7 +43,7 @@ jerry_debugger_stop (void)
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
}
#endif /* JERRY_DEBUGGER */
@ -59,7 +59,7 @@ jerry_debugger_continue (void)
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
}
#endif /* JERRY_DEBUGGER */
@ -77,11 +77,11 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) /**< enable/d
{
if (enable_stop_at_breakpoint)
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_IGNORE);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
}
else
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_IGNORE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
}
}
#else /* !JERRY_DEBUGGER */
@ -122,7 +122,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
jerry_debugger_uint8_data_t *client_source_data_p = NULL;
jerry_debugger_wait_for_source_status_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
@ -142,8 +142,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONTEXT_RESET_MODE))
{
ret_type = JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED;
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CONTEXT_RESET_MODE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE);
break;
}
@ -151,8 +150,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_NO_SOURCE))
{
ret_type = JERRY_DEBUGGER_SOURCE_END;
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
break;
}

View File

@ -69,7 +69,7 @@ jerry_debugger_close_connection_tcp (bool log_error) /**< log error */
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
JERRY_CONTEXT (debugger_flags) = (uint8_t) JERRY_DEBUGGER_VM_IGNORE;
JERRY_CONTEXT (debugger_flags) = JERRY_DEBUGGER_VM_IGNORE;
if (log_error)
{
@ -360,7 +360,7 @@ jerry_debugger_accept_connection (void)
close (server_socket);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CONNECTED);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CONNECTED);
bool is_handshake_ok = false;
@ -399,7 +399,7 @@ jerry_debugger_accept_connection (void)
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Connected from: %s\n", inet_ntoa (addr.sin_addr));
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
return true;
@ -444,7 +444,7 @@ jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out]
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
JERRY_ASSERT (message_data_p != NULL ? (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)
JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)
: !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE));
JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY;

View File

@ -34,8 +34,8 @@
* The number of message types in the debugger should reflect the
* debugger versioning.
*/
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 26
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 16
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 18
&& JERRY_DEBUGGER_VERSION == 1,
debugger_version_correlates_to_message_type_count);
@ -154,9 +154,9 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE));
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_IGNORE);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p, eval_string_size, true, false);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_IGNORE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
if (!ECMA_IS_VALUE_ERROR (result))
{
@ -325,8 +325,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
else
{
result = true;
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
}
@ -407,7 +406,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
*resume_exec_p = false;
return true;
@ -417,7 +416,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
*resume_exec_p = true;
return true;
@ -427,7 +426,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
*resume_exec_p = true;
return true;
@ -437,7 +436,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p);
*resume_exec_p = true;
return true;
@ -456,20 +455,51 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
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_DEBUGGER_SET_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_DEBUGGER_CLEAR_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_PARSER_CONFIG:
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_parser_config_t);
JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_parser_config_t, parser_config_p);
if (parser_config_p->enable_wait != 0)
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing enabled\n");
}
else
{
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing disabled\n");
}
return true;
}
case JERRY_DEBUGGER_PARSER_RESUME:
{
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in parser wait mode\n");
jerry_debugger_close_connection ();
return false;
}
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE);
return true;
}
@ -568,8 +598,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
}
else
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
}
return true;
@ -586,8 +615,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_NO_SOURCE);
JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CLIENT_NO_SOURCE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
@ -605,8 +633,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CONTEXT_RESET_MODE);
JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
@ -652,7 +679,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
return;
}
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_BREAKPOINT_MODE);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE);
jerry_debugger_uint8_data_t *uint8_data = NULL;
@ -667,7 +694,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
uint8_data->uint8_size + sizeof (jerry_debugger_uint8_data_t));
}
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_BREAKPOINT_MODE);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE);
JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY;
} /* jerry_debugger_breakpoint_hit */

View File

@ -93,18 +93,41 @@ typedef enum
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_CLIENT_SOURCE_MODE = 1u << 5, /**< debugger waiting for client code */
JERRY_DEBUGGER_CLIENT_NO_SOURCE = 1u << 6, /**< debugger leaving the client source loop */
JERRY_DEBUGGER_CONTEXT_RESET_MODE = 1u << 7, /**< debugger and engine reinitialization mode */
JERRY_DEBUGGER_PARSER_WAIT = 1u << 5, /**< debugger should wait after parsing is completed */
JERRY_DEBUGGER_PARSER_WAIT_MODE = 1u << 6, /**< debugger is waiting after parsing is completed */
JERRY_DEBUGGER_CLIENT_SOURCE_MODE = 1u << 7, /**< debugger waiting for client code */
JERRY_DEBUGGER_CLIENT_NO_SOURCE = 1u << 8, /**< debugger leaving the client source loop */
JERRY_DEBUGGER_CONTEXT_RESET_MODE = 1u << 9, /**< debugger and engine reinitialization mode */
} jerry_debugger_flags_t;
/**
* Set debugger flags.
*/
#define JERRY_DEBUGGER_SET_FLAGS(flags) \
JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags))
/**
* Clear debugger flags.
*/
#define JERRY_DEBUGGER_CLEAR_FLAGS(flags) \
JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) & (uint32_t) ~(flags))
/**
* Set and clear debugger flags.
*/
#define JERRY_DEBUGGER_UPDATE_FLAGS(flags_to_set, flags_to_clear) \
JERRY_CONTEXT (debugger_flags) = ((JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags_to_set)) \
& (uint32_t) ~(flags_to_clear))
/**
* Types for the package.
*/
typedef enum
{
/* Messages sent by the server to client. */
/* This is a handshake message, sent once during initialization. */
JERRY_DEBUGGER_CONFIGURATION = 1, /**< debugger configuration */
/* These messages are sent by the parser. */
JERRY_DEBUGGER_PARSE_ERROR = 2, /**< parse error */
JERRY_DEBUGGER_BYTE_CODE_CP = 3, /**< byte code compressed pointer */
JERRY_DEBUGGER_PARSE_FUNCTION = 4, /**< parsing a new function */
@ -116,19 +139,21 @@ typedef enum
JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10, /**< source code name last fragment */
JERRY_DEBUGGER_FUNCTION_NAME = 11, /**< function name fragment */
JERRY_DEBUGGER_FUNCTION_NAME_END = 12, /**< function name last fragment */
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13, /**< invalidate byte code compressed pointer */
JERRY_DEBUGGER_MEMSTATS_RECEIVE = 14, /**< memstats sent to the client*/
JERRY_DEBUGGER_BREAKPOINT_HIT = 15, /**< notify breakpoint hit */
JERRY_DEBUGGER_EXCEPTION_HIT = 16, /**< notify exception hit */
JERRY_DEBUGGER_EXCEPTION_STR = 17, /**< exception string fragment */
JERRY_DEBUGGER_EXCEPTION_STR_END = 18, /**< exception string last fragment */
JERRY_DEBUGGER_BACKTRACE = 19, /**< backtrace data */
JERRY_DEBUGGER_BACKTRACE_END = 20, /**< last backtrace data */
JERRY_DEBUGGER_EVAL_RESULT = 21, /**< eval result */
JERRY_DEBUGGER_EVAL_RESULT_END = 22, /**< last part of eval result */
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23, /**< engine waiting for a source code */
JERRY_DEBUGGER_OUTPUT_RESULT = 24, /**< output sent by the program to the debugger */
JERRY_DEBUGGER_OUTPUT_RESULT_END = 25, /**< last output result data */
JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13, /**< engine waiting for a parser resume */
/* These messages are generic messages. */
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14, /**< invalidate byte code compressed pointer */
JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15, /**< memstats sent to the client*/
JERRY_DEBUGGER_BREAKPOINT_HIT = 16, /**< notify breakpoint hit */
JERRY_DEBUGGER_EXCEPTION_HIT = 17, /**< notify exception hit */
JERRY_DEBUGGER_EXCEPTION_STR = 18, /**< exception string fragment */
JERRY_DEBUGGER_EXCEPTION_STR_END = 19, /**< exception string last fragment */
JERRY_DEBUGGER_BACKTRACE = 20, /**< backtrace data */
JERRY_DEBUGGER_BACKTRACE_END = 21, /**< last backtrace data */
JERRY_DEBUGGER_EVAL_RESULT = 22, /**< eval result */
JERRY_DEBUGGER_EVAL_RESULT_END = 23, /**< last part of eval result */
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24, /**< engine waiting for a source code */
JERRY_DEBUGGER_OUTPUT_RESULT = 25, /**< output sent by the program to the debugger */
JERRY_DEBUGGER_OUTPUT_RESULT_END = 26, /**< last output result data */
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
@ -138,22 +163,26 @@ typedef enum
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */
JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2, /**< update breakpoint status */
JERRY_DEBUGGER_EXCEPTION_CONFIG = 3, /**< exception handler config */
JERRY_DEBUGGER_MEMSTATS = 4, /**< list memory statistics */
JERRY_DEBUGGER_STOP = 5, /**< stop execution */
JERRY_DEBUGGER_CLIENT_SOURCE = 6, /**< first message of client source */
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7, /**< next message of client source */
JERRY_DEBUGGER_NO_MORE_SOURCES = 8, /**< no more sources notification */
JERRY_DEBUGGER_CONTEXT_RESET = 9, /**< context reset request */
JERRY_DEBUGGER_PARSER_CONFIG = 4, /**< parser config */
JERRY_DEBUGGER_MEMSTATS = 5, /**< list memory statistics */
JERRY_DEBUGGER_STOP = 6, /**< stop execution */
/* The following message is only available in waiting after parse mode. */
JERRY_DEBUGGER_PARSER_RESUME = 7, /**< stop waiting after parse */
/* The following four messages are only available in client switch mode. */
JERRY_DEBUGGER_CLIENT_SOURCE = 8, /**< first message of client source */
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9, /**< next message of client source */
JERRY_DEBUGGER_NO_MORE_SOURCES = 10, /**< no more sources notification */
JERRY_DEBUGGER_CONTEXT_RESET = 11, /**< context reset request */
/* The following messages are only available in breakpoint
* mode and they switch the engine to run mode. */
JERRY_DEBUGGER_CONTINUE = 10, /**< continue execution */
JERRY_DEBUGGER_STEP = 11, /**< next breakpoint, step into functions */
JERRY_DEBUGGER_NEXT = 12, /**< next breakpoint in the same context */
JERRY_DEBUGGER_CONTINUE = 12, /**< continue execution */
JERRY_DEBUGGER_STEP = 13, /**< next breakpoint, step into functions */
JERRY_DEBUGGER_NEXT = 14, /**< 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 = 13, /**< get backtrace */
JERRY_DEBUGGER_EVAL = 14, /**< first message of evaluating a string */
JERRY_DEBUGGER_EVAL_PART = 15, /**< next message of evaluating a string */
JERRY_DEBUGGER_GET_BACKTRACE = 15, /**< get backtrace */
JERRY_DEBUGGER_EVAL = 16, /**< first message of evaluating a string */
JERRY_DEBUGGER_EVAL_PART = 17, /**< next message of evaluating a string */
JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT, /**< number of different type of input messages */
} jerry_debugger_header_type_t;
@ -313,12 +342,24 @@ typedef struct
jerry_debugger_frame_t frames[JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t)]; /**< frames */
} jerry_debugger_send_backtrace_t;
/**
* Incoming message: set behaviour when exception occures.
*/
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: set parser configuration.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t enable_wait; /**< non-zero: wait after parsing is completed */
} jerry_debugger_receive_parser_config_t;
/**
* Incoming message: get backtrace.
*/

View File

@ -116,11 +116,11 @@ typedef struct
vm_frame_ctx_t *debugger_stop_context; /**< stop only if the current context is equal to this context */
jmem_cpointer_t debugger_byte_code_free_head; /**< head of byte code free linked list */
jmem_cpointer_t debugger_byte_code_free_tail; /**< tail of byte code free linked list */
uint8_t debugger_flags; /**< debugger flags */
uint8_t debugger_message_delay; /**< call receive message when reaches zero */
uint32_t debugger_flags; /**< debugger flags */
uint16_t debugger_receive_buffer_offset; /**< receive buffer offset */
int debugger_connection; /**< holds the file descriptor of the socket communication */
uint16_t debugger_port; /**< debugger socket communication port */
uint8_t debugger_message_delay; /**< call receive message when reaches zero */
int debugger_connection; /**< holds the file descriptor of the socket communication */
#endif /* JERRY_DEBUGGER */
#ifdef JMEM_STATS

View File

@ -2275,7 +2275,7 @@ parser_save_context (parser_context_t *context_p, /**< context */
JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
#ifdef JERRY_DEBUGGER
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& context_p->breakpoint_info_count > 0)
{
parser_send_breakpoints (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST);
@ -2756,6 +2756,28 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
return ecma_raise_syntax_error ("");
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
}
#ifdef JERRY_DEBUGGER
if ((JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
== (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE);
jerry_debugger_send_type (JERRY_DEBUGGER_WAITING_AFTER_PARSE);
while (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE)
{
jerry_debugger_receive (NULL);
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED))
{
break;
}
jerry_debugger_sleep ();
}
}
#endif /* JERRY_DEBUGGER */
return ECMA_VALUE_TRUE;
#else /* JERRY_DISABLE_JS_PARSER */
JERRY_UNUSED (arg_list_p);

View File

@ -51,19 +51,20 @@ 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_MEMSTATS_RECEIVE = 14;
var JERRY_DEBUGGER_BREAKPOINT_HIT = 15;
var JERRY_DEBUGGER_EXCEPTION_HIT = 16;
var JERRY_DEBUGGER_EXCEPTION_STR = 17;
var JERRY_DEBUGGER_EXCEPTION_STR_END = 18;
var JERRY_DEBUGGER_BACKTRACE = 19;
var JERRY_DEBUGGER_BACKTRACE_END = 20;
var JERRY_DEBUGGER_EVAL_RESULT = 21;
var JERRY_DEBUGGER_EVAL_RESULT_END = 22;
var JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23;
var JERRY_DEBUGGER_OUTPUT_RESULT = 24;
var JERRY_DEBUGGER_OUTPUT_RESULT_END = 25;
var JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13;
var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14;
var JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15;
var JERRY_DEBUGGER_BREAKPOINT_HIT = 16;
var JERRY_DEBUGGER_EXCEPTION_HIT = 17;
var JERRY_DEBUGGER_EXCEPTION_STR = 18;
var JERRY_DEBUGGER_EXCEPTION_STR_END = 19;
var JERRY_DEBUGGER_BACKTRACE = 20;
var JERRY_DEBUGGER_BACKTRACE_END = 21;
var JERRY_DEBUGGER_EVAL_RESULT = 22;
var JERRY_DEBUGGER_EVAL_RESULT_END = 23;
var JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24;
var JERRY_DEBUGGER_OUTPUT_RESULT = 25;
var JERRY_DEBUGGER_OUTPUT_RESULT_END = 26;
// Subtypes of eval
var JERRY_DEBUGGER_EVAL_OK = 1;
@ -80,18 +81,20 @@ var JERRY_DEBUGGER_OUTPUT_TRACE = 5;
var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1;
var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
var JERRY_DEBUGGER_EXCEPTION_CONFIG = 3;
var JERRY_DEBUGGER_MEMSTATS = 4;
var JERRY_DEBUGGER_STOP = 5;
var JERRY_DEBUGGER_CLIENT_SOURCE = 6;
var JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7;
var JERRY_DEBUGGER_NO_MORE_SOURCES = 8;
var JERRY_DEBUGGER_CONTEXT_RESET = 9;
var JERRY_DEBUGGER_CONTINUE = 10;
var JERRY_DEBUGGER_STEP = 11;
var JERRY_DEBUGGER_NEXT = 12;
var JERRY_DEBUGGER_GET_BACKTRACE = 13;
var JERRY_DEBUGGER_EVAL = 14;
var JERRY_DEBUGGER_EVAL_PART = 15;
var JERRY_DEBUGGER_PARSER_CONFIG = 4;
var JERRY_DEBUGGER_MEMSTATS = 5;
var JERRY_DEBUGGER_STOP = 6;
var JERRY_DEBUGGER_PARSER_RESUME = 7;
var JERRY_DEBUGGER_CLIENT_SOURCE = 8;
var JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9;
var JERRY_DEBUGGER_NO_MORE_SOURCES = 10;
var JERRY_DEBUGGER_CONTEXT_RESET = 11;
var JERRY_DEBUGGER_CONTINUE = 12;
var JERRY_DEBUGGER_STEP = 13;
var JERRY_DEBUGGER_NEXT = 14;
var JERRY_DEBUGGER_GET_BACKTRACE = 15;
var JERRY_DEBUGGER_EVAL = 16;
var JERRY_DEBUGGER_EVAL_PART = 17;
var textBox = document.getElementById("log");
var commandBox = document.getElementById("command");

View File

@ -41,19 +41,20 @@ 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_MEMSTATS_RECEIVE = 14
JERRY_DEBUGGER_BREAKPOINT_HIT = 15
JERRY_DEBUGGER_EXCEPTION_HIT = 16
JERRY_DEBUGGER_EXCEPTION_STR = 17
JERRY_DEBUGGER_EXCEPTION_STR_END = 18
JERRY_DEBUGGER_BACKTRACE = 19
JERRY_DEBUGGER_BACKTRACE_END = 20
JERRY_DEBUGGER_EVAL_RESULT = 21
JERRY_DEBUGGER_EVAL_RESULT_END = 22
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23
JERRY_DEBUGGER_OUTPUT_RESULT = 24
JERRY_DEBUGGER_OUTPUT_RESULT_END = 25
JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14
JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15
JERRY_DEBUGGER_BREAKPOINT_HIT = 16
JERRY_DEBUGGER_EXCEPTION_HIT = 17
JERRY_DEBUGGER_EXCEPTION_STR = 18
JERRY_DEBUGGER_EXCEPTION_STR_END = 19
JERRY_DEBUGGER_BACKTRACE = 20
JERRY_DEBUGGER_BACKTRACE_END = 21
JERRY_DEBUGGER_EVAL_RESULT = 22
JERRY_DEBUGGER_EVAL_RESULT_END = 23
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24
JERRY_DEBUGGER_OUTPUT_RESULT = 25
JERRY_DEBUGGER_OUTPUT_RESULT_END = 26
# Subtypes of eval
JERRY_DEBUGGER_EVAL_OK = 1
@ -71,18 +72,20 @@ JERRY_DEBUGGER_OUTPUT_TRACE = 5
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2
JERRY_DEBUGGER_EXCEPTION_CONFIG = 3
JERRY_DEBUGGER_MEMSTATS = 4
JERRY_DEBUGGER_STOP = 5
JERRY_DEBUGGER_CLIENT_SOURCE = 6
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7
JERRY_DEBUGGER_NO_MORE_SOURCES = 8
JERRY_DEBUGGER_CONTEXT_RESET = 9
JERRY_DEBUGGER_CONTINUE = 10
JERRY_DEBUGGER_STEP = 11
JERRY_DEBUGGER_NEXT = 12
JERRY_DEBUGGER_GET_BACKTRACE = 13
JERRY_DEBUGGER_EVAL = 14
JERRY_DEBUGGER_EVAL_PART = 15
JERRY_DEBUGGER_PARSER_CONFIG = 4
JERRY_DEBUGGER_MEMSTATS = 5
JERRY_DEBUGGER_STOP = 6
JERRY_DEBUGGER_PARSER_RESUME = 7
JERRY_DEBUGGER_CLIENT_SOURCE = 8
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9
JERRY_DEBUGGER_NO_MORE_SOURCES = 10
JERRY_DEBUGGER_CONTEXT_RESET = 11
JERRY_DEBUGGER_CONTINUE = 12
JERRY_DEBUGGER_STEP = 13
JERRY_DEBUGGER_NEXT = 14
JERRY_DEBUGGER_GET_BACKTRACE = 15
JERRY_DEBUGGER_EVAL = 16
JERRY_DEBUGGER_EVAL_PART = 17
MAX_BUFFER_SIZE = 128
WEBSOCKET_BINARY_FRAME = 2
@ -315,6 +318,8 @@ class DebuggerPrompt(Cmd):
self.debugger.send_breakpoint(breakpoint)
elif breakpoint_index in self.debugger.pending_breakpoint_list:
del self.debugger.pending_breakpoint_list[breakpoint_index]
if not self.debugger.pending_breakpoint_list:
self.debugger.send_parser_config(0)
else:
print("Error: Breakpoint %d not found" % (breakpoint_index))
@ -636,7 +641,9 @@ class JerryDebugger(object):
self.send_breakpoint(breakpoint)
def delete_pending(self):
self.pending_breakpoint_list.clear()
if self.pending_breakpoint_list:
self.pending_breakpoint_list.clear()
self.send_parser_config(0)
def breakpoint_pending_exists(self, breakpoint):
for existing_bp in self.pending_breakpoint_list.values():
@ -684,13 +691,22 @@ class JerryDebugger(object):
enable)
self.send_message(message)
def send_parser_config(self, enable):
message = struct.pack(self.byte_order + "BBIBB",
WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
WEBSOCKET_FIN_BIT + 1 + 1,
0,
JERRY_DEBUGGER_PARSER_CONFIG,
enable)
self.send_message(message)
def set_colors(self):
self.green = '\033[92m'
self.nocolor = '\033[0m'
self.green = '\033[92m'
self.red = '\033[31m'
self.yellow = '\033[93m'
self.green_bg = '\033[42m'
self.yellow_bg = '\033[43m'
self.green_bg = '\033[42m\033[30m'
self.yellow_bg = '\033[43m\033[30m'
self.blue = '\033[94m'
def get_message(self, blocking):
@ -843,29 +859,29 @@ def parse_source(debugger, data):
debugger.line_list.insert(line, breakpoint)
# Try to set the pending breakpoints
if len(debugger.pending_breakpoint_list) != 0:
if debugger.pending_breakpoint_list:
logging.debug("Pending breakpoints list: %s", debugger.pending_breakpoint_list)
bp_list = debugger.pending_breakpoint_list
for breakpoint in bp_list:
for breakpoint_index, breakpoint in bp_list.items():
for src in debugger.function_list.values():
if src.source_name == bp_list[breakpoint].source_name:
if src.source_name == breakpoint.source_name:
source_lines = len(src.source)
else:
source_lines = 0
if bp_list[breakpoint].line:
if bp_list[breakpoint].line <= source_lines:
tmp_bp = breakpoint
breakpoint = bp_list[breakpoint].source_name + ":" + str(bp_list[breakpoint].line)
if set_breakpoint(debugger, breakpoint, True):
del tmp_bp
elif bp_list[breakpoint].function:
tmp_bp = breakpoint
breakpoint = bp_list[breakpoint].function
if set_breakpoint(debugger, breakpoint, True):
del tmp_bp
if breakpoint.line:
if breakpoint.line <= source_lines:
command = breakpoint.source_name + ":" + str(breakpoint.line)
if set_breakpoint(debugger, command, True):
del bp_list[breakpoint_index]
elif breakpoint.function:
command = breakpoint.function
if set_breakpoint(debugger, command, True):
del bp_list[breakpoint_index]
if not bp_list:
debugger.send_parser_config(0)
else:
logging.debug("No pending breakpoints")
@ -971,14 +987,19 @@ def set_breakpoint(debugger, string, pending):
if not found and not pending:
print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \
(debugger.yellow, debugger.nocolor))
(debugger.yellow, debugger.nocolor))
ans = sys.stdin.readline()
if ans in ['yes\n', 'y\n']:
if not debugger.pending_breakpoint_list:
debugger.send_parser_config(1)
if line:
breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1))
else:
breakpoint = JerryPendingBreakpoint(function=string)
enable_breakpoint(debugger, breakpoint)
elif not found and pending:
return False
@ -1062,6 +1083,9 @@ def main():
JERRY_DEBUGGER_FUNCTION_NAME_END]:
parse_source(debugger, data)
elif buffer_type == JERRY_DEBUGGER_WAITING_AFTER_PARSE:
debugger.send_command(JERRY_DEBUGGER_PARSER_RESUME)
elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
release_function(debugger, data)

View File

@ -1,7 +1,9 @@
break :1
y
break f
y
list
n
n
c
list
c
c

View File

@ -1,17 +1,24 @@
Connecting to: localhost:5001
Stopped at tests/debugger/do_pending_breakpoints.js:15
(jerry-debugger) break :1
No breakpoint found, do you want to add a pending breakpoint? (y or [n])
Pending breakpoint at :1
(jerry-debugger) break f
No breakpoint found, do you want to add a pending breakpoint? (y or [n])
Pending breakpoint at f()
(jerry-debugger) list
=== Pending breakpoints ===
1: f() (pending)
(jerry-debugger) n
1: :1 (pending)
2: f() (pending)
(jerry-debugger) c
out: pending-breakpoints
Stopped at tests/debugger/do_pending_breakpoints.js:17
(jerry-debugger) n
Breakpoint 2 at <unknown>:1 (in f() at line:1, col:1)
Stopped at tests/debugger/do_pending_breakpoints.js:19
Breakpoint 3 at <unknown>:1
Breakpoint 4 at <unknown>:3 (in f() at line:2, col:1)
Stopped at breakpoint:3 <unknown>:1
(jerry-debugger) list
=== Active breakpoints ===
3: <unknown>:1
4: <unknown>:3 (in f() at line:2, col:1)
(jerry-debugger) c
Stopped at breakpoint:2 <unknown>:1 (in f() at line:1, col:1)
Stopped at breakpoint:4 <unknown>:3 (in f() at line:2, col:1)
(jerry-debugger) c

View File

@ -14,7 +14,7 @@
print("pending-breakpoints");
eval("function f(){ return 5 }");
eval("1;\nfunction f()\n{ return 5 }");
var bird = "colibri";
f();