Add source sending feature to the debugger. (#1932)

With this feature the debugger webIDE and the python client can able to send a source code to the debugger while that is running in wait mode.
This feature can be activated with the --debugger-wait-source switch and the debugger will wait for the source messages.
If every message part are received the debugger will continue the exectuion with the initalized options.

JerryScript-DCO-1.0-Signed-off-by: Imre Kiss kissi.szeged@partner.samsung.com
This commit is contained in:
Imre Kiss
2017-08-03 14:29:47 +02:00
committed by Zoltan Herczeg
parent a3885be6ce
commit 3e3d6373b8
16 changed files with 423 additions and 86 deletions
+109 -38
View File
@@ -45,11 +45,6 @@
#define JERRY_DEBUGGER_RECEIVE_BUFFER_AS(type, name_p) \
type *name_p = ((type *) recv_buffer_p)
/**
* Sleep time in milliseconds between each jerry_debugger_receive call
*/
#define JERRY_DEBUGGER_TIMEOUT 100
/**
* Free all unreferenced byte code structures which
* were not acknowledged by the debugger client.
@@ -218,19 +213,17 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
* Suspend execution for a given time.
* Note: If the platform does not have nanosleep or usleep, this function does not sleep at all.
*/
static void
jerry_debugger_sleep (unsigned milliseconds) /**< suspending time */
void
jerry_debugger_sleep (void)
{
#ifdef HAVE_TIME_H
nanosleep (&(const struct timespec)
{
milliseconds / 1000, (milliseconds % 1000) * 1000000L /* Seconds, nanoseconds */
JERRY_DEBUGGER_TIMEOUT / 1000, (JERRY_DEBUGGER_TIMEOUT % 1000) * 1000000L /* Seconds, nanoseconds */
}
, NULL);
#elif defined (HAVE_UNISTD_H)
usleep ((useconds_t) milliseconds * 1000);
#else /* If neither of the libs found */
JERRY_UNUSED (milliseconds);
usleep ((useconds_t) JERRY_DEBUGGER_TIMEOUT * 1000);
#endif /* HAVE_TIME_H */
} /* jerry_debugger_sleep */
@@ -255,8 +248,8 @@ inline bool __attr_always_inline___
jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the received data */
uint32_t message_size, /**< message size */
bool *resume_exec_p, /**< pointer to the resume exec flag */
uint8_t *expected_message_type_p, /**< expected message type */
void **message_data_p) /**< custom message data */
uint8_t *expected_message_type_p, /**< message type */
jerry_debugger_uint8_data_t **message_data_p) /**< custom message data */
{
/* Process the received message. */
@@ -270,53 +263,65 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
if (*expected_message_type_p != 0)
{
JERRY_ASSERT (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART);
JERRY_ASSERT (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART
|| *expected_message_type_p == JERRY_DEBUGGER_CLIENT_SOURCE_PART);
jerry_debugger_eval_data_t *eval_data_p = (jerry_debugger_eval_data_t *) *message_data_p;
jerry_debugger_uint8_data_t *uint8_data_p = (jerry_debugger_uint8_data_t *) *message_data_p;
if (recv_buffer_p[0] != JERRY_DEBUGGER_EVAL_PART)
if (recv_buffer_p[0] != *expected_message_type_p)
{
jmem_heap_free_block (eval_data_p, eval_data_p->eval_size + sizeof (jerry_debugger_eval_data_t));
jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unexpected message\n");
jerry_debugger_close_connection ();
return false;
}
JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_eval_part_t, eval_part_p);
JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_uint8_data_part_t, uint8_data_part_p);
if (message_size < sizeof (jerry_debugger_receive_eval_part_t) + 1)
if (message_size < sizeof (jerry_debugger_receive_uint8_data_part_t) + 1)
{
jmem_heap_free_block (eval_data_p, eval_data_p->eval_size + sizeof (jerry_debugger_eval_data_t));
jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
jerry_debugger_close_connection ();
return false;
}
uint32_t expected_data = eval_data_p->eval_size - eval_data_p->eval_offset;
uint32_t expected_data = uint8_data_p->uint8_size - uint8_data_p->uint8_offset;
message_size -= (uint32_t) sizeof (jerry_debugger_receive_eval_part_t);
message_size -= (uint32_t) sizeof (jerry_debugger_receive_uint8_data_part_t);
if (message_size > expected_data)
{
jmem_heap_free_block (eval_data_p, eval_data_p->eval_size + sizeof (jerry_debugger_eval_data_t));
jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
jerry_debugger_close_connection ();
return false;
}
lit_utf8_byte_t *eval_string_p = (lit_utf8_byte_t *) (eval_data_p + 1);
memcpy (eval_string_p + eval_data_p->eval_offset,
(lit_utf8_byte_t *) (eval_part_p + 1),
lit_utf8_byte_t *string_p = (lit_utf8_byte_t *) (uint8_data_p + 1);
memcpy (string_p + uint8_data_p->uint8_offset,
(lit_utf8_byte_t *) (uint8_data_part_p + 1),
message_size);
if (message_size < expected_data)
{
eval_data_p->eval_offset += message_size;
uint8_data_p->uint8_offset += message_size;
return true;
}
bool result = jerry_debugger_send_eval (eval_string_p, eval_data_p->eval_size);
jmem_heap_free_block (eval_data_p, eval_data_p->eval_size + sizeof (jerry_debugger_eval_data_t));
bool result = false;
if (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART)
{
result = jerry_debugger_send_eval (string_p, uint8_data_p->uint8_size);
}
else
{
result = true;
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
}
*expected_message_type_p = 0;
return result;
}
@@ -486,24 +491,82 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
return jerry_debugger_send_eval ((lit_utf8_byte_t *) (eval_first_p + 1), eval_size);
}
jerry_debugger_eval_data_t *eval_data_p;
size_t eval_data_size = sizeof (jerry_debugger_eval_data_t) + eval_size;
jerry_debugger_uint8_data_t *eval_uint8_data_p;
size_t eval_data_size = sizeof (jerry_debugger_uint8_data_t) + eval_size;
eval_data_p = (jerry_debugger_eval_data_t *) jmem_heap_alloc_block (eval_data_size);
eval_uint8_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (eval_data_size);
eval_data_p->eval_size = eval_size;
eval_data_p->eval_offset = (uint32_t) (message_size - sizeof (jerry_debugger_receive_eval_first_t));
eval_uint8_data_p->uint8_size = eval_size;
eval_uint8_data_p->uint8_offset = (uint32_t) (message_size - sizeof (jerry_debugger_receive_eval_first_t));
lit_utf8_byte_t *eval_string_p = (lit_utf8_byte_t *) (eval_data_p + 1);
lit_utf8_byte_t *eval_string_p = (lit_utf8_byte_t *) (eval_uint8_data_p + 1);
memcpy (eval_string_p,
(lit_utf8_byte_t *) (eval_first_p + 1),
message_size - sizeof (jerry_debugger_receive_eval_first_t));
*message_data_p = eval_data_p;
*message_data_p = eval_uint8_data_p;
*expected_message_type_p = JERRY_DEBUGGER_EVAL_PART;
return true;
}
case JERRY_DEBUGGER_CLIENT_SOURCE:
{
if (message_size <= sizeof (jerry_debugger_receive_client_source_first_t))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
jerry_debugger_close_connection ();
return false;
}
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in client source mode\n");
jerry_debugger_close_connection ();
return false;
}
JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_client_source_first_t, client_source_first_p);
uint32_t client_source_size;
memcpy (&client_source_size, client_source_first_p->code_size, sizeof (uint32_t));
if (client_source_size <= JERRY_DEBUGGER_MAX_RECEIVE_SIZE - sizeof (jerry_debugger_receive_client_source_first_t)
&& client_source_size != message_size - sizeof (jerry_debugger_receive_client_source_first_t))
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
jerry_debugger_close_connection ();
return false;
}
jerry_debugger_uint8_data_t *client_source_data_p;
size_t client_source_data_size = sizeof (jerry_debugger_uint8_data_t) + client_source_size;
client_source_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (client_source_data_size);
client_source_data_p->uint8_size = client_source_size;
client_source_data_p->uint8_offset = (uint32_t) (message_size
- sizeof (jerry_debugger_receive_client_source_first_t));
lit_utf8_byte_t *client_source_string_p = (lit_utf8_byte_t *) (client_source_data_p + 1);
memcpy (client_source_string_p,
(lit_utf8_byte_t *) (client_source_first_p + 1),
message_size - sizeof (jerry_debugger_receive_client_source_first_t));
*message_data_p = client_source_data_p;
if (client_source_data_p->uint8_size != client_source_data_p->uint8_offset)
{
*expected_message_type_p = JERRY_DEBUGGER_CLIENT_SOURCE_PART;
}
else
{
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags)
& ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
*resume_exec_p = true;
}
return true;
}
default:
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unexpected message.");
@@ -545,9 +608,17 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_BREAKPOINT_MODE);
while (!jerry_debugger_receive ())
jerry_debugger_uint8_data_t *uint8_data = NULL;
while (!jerry_debugger_receive (&uint8_data))
{
jerry_debugger_sleep (JERRY_DEBUGGER_TIMEOUT);
jerry_debugger_sleep ();
}
if (uint8_data != NULL)
{
jmem_heap_free_block (uint8_data,
uint8_data->uint8_size + sizeof (jerry_debugger_uint8_data_t));
}
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_BREAKPOINT_MODE);