mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Multiple client source sending feature. (#1957)
Whit this enhancement the debugger can able handle more than one source file across the new source wait mode. This feature can be used by the python client with the --client-source [paths] switch. The client will store every source path, when the debugger send a signal about the waiting status, then the client will send one file from the list. JerryScript-DCO-1.0-Signed-off-by: Imre Kiss kissi.szeged@partner.samsung.com
This commit is contained in:
parent
2888a6f488
commit
3b1d578050
@ -26,7 +26,7 @@ can be used for transmitting debugger messages.
|
||||
|
||||
The debugger client must be connected to the server before the
|
||||
JavaScript application runs. On-the-fly attachment is supported
|
||||
for one file, right after of engine initialization
|
||||
for more than one file, right after of engine initialization
|
||||
(this feature available with the python client). The debugging
|
||||
information (e.g. line index of each possible -breakpoint location)
|
||||
is not preserved by JerryScript. The client is expected to be run
|
||||
@ -208,7 +208,8 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
|
||||
|
||||
Stops the engine and puts that into a waiting loop. If the client send
|
||||
a source code and the JerryScript receive that, then the function will
|
||||
run the source with the initialized options.
|
||||
run the source with the initialized options, after that the engine will
|
||||
wait for a new source until the client send a close signal.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@ -222,12 +223,19 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value)
|
||||
```c
|
||||
jerry_init (JERRY_INIT_DEBUGGER);
|
||||
|
||||
jerry_value_t wait_and_run_value;
|
||||
jerry_value_t run_result;
|
||||
jerry_debugger_wait_and_run_type_t receive_status;
|
||||
|
||||
if (jerry_debugger_wait_and_run_client_source (&wait_and_run_value) == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
do
|
||||
{
|
||||
// Handle the fail (e.g. create an error).
|
||||
}
|
||||
receive_status = jerry_debugger_wait_and_run_client_source (&run_result);
|
||||
|
||||
jerry_release_value (wait_and_run_value);
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
// Handle the fail (e.g. create an error).
|
||||
}
|
||||
|
||||
jerry_release_value (run_result);
|
||||
}
|
||||
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
```
|
||||
|
||||
@ -121,7 +121,8 @@ jerry_debugger_cleanup (void)
|
||||
* Sets whether the engine should wait and run a source.
|
||||
*
|
||||
* @return enum JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED - if the source is not received
|
||||
* JERRY_DEBUGGER_SOURCE_RECEIVED - if the source received
|
||||
* JERRY_DEBUGGER_SOURCE_RECEIVED - if a source code received
|
||||
* JERRY_DEBUGGER_SOURCE_END - the end of the source codes
|
||||
*/
|
||||
jerry_debugger_wait_and_run_type_t
|
||||
jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [out] parse and run return value */
|
||||
@ -136,6 +137,9 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [ou
|
||||
jerry_debugger_uint8_data_t *client_source_data_p = NULL;
|
||||
jerry_debugger_wait_and_run_type_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
|
||||
|
||||
/* Notify the client about that the engine is waiting for a source. */
|
||||
jerry_debugger_send_type (JERRY_DEBUGGER_WAIT_FOR_SOURCE);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (jerry_debugger_receive (&client_source_data_p))
|
||||
@ -145,6 +149,13 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [ou
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stop waiting for a new source file. */
|
||||
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_NO_SOURCE))
|
||||
{
|
||||
ret_type = JERRY_DEBUGGER_SOURCE_END;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The source arrived. */
|
||||
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
|
||||
{
|
||||
|
||||
@ -568,6 +568,25 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec
|
||||
return true;
|
||||
}
|
||||
|
||||
case JERRY_DEBUGGER_NO_MORE_SOURCES:
|
||||
{
|
||||
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_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);
|
||||
|
||||
*resume_exec_p = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unexpected message.");
|
||||
|
||||
@ -89,6 +89,7 @@ typedef enum
|
||||
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_flags_t;
|
||||
|
||||
/**
|
||||
@ -119,6 +120,7 @@ typedef enum
|
||||
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 */
|
||||
|
||||
/* Messages sent by the client to server. */
|
||||
|
||||
@ -130,16 +132,17 @@ typedef enum
|
||||
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 */
|
||||
/* The following messages are only available in breakpoint
|
||||
* mode and they switch the engine to run mode. */
|
||||
JERRY_DEBUGGER_CONTINUE = 8, /**< continue execution */
|
||||
JERRY_DEBUGGER_STEP = 9, /**< next breakpoint, step into functions */
|
||||
JERRY_DEBUGGER_NEXT = 10, /**< next breakpoint in the same context */
|
||||
JERRY_DEBUGGER_CONTINUE = 9, /**< continue execution */
|
||||
JERRY_DEBUGGER_STEP = 10, /**< next breakpoint, step into functions */
|
||||
JERRY_DEBUGGER_NEXT = 11, /**< 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 = 11, /**< get backtrace */
|
||||
JERRY_DEBUGGER_EVAL = 12, /**< first message of evaluating a string */
|
||||
JERRY_DEBUGGER_EVAL_PART = 13, /**< next message of evaluating a string */
|
||||
JERRY_DEBUGGER_GET_BACKTRACE = 12, /**< get backtrace */
|
||||
JERRY_DEBUGGER_EVAL = 13, /**< first message of evaluating a string */
|
||||
JERRY_DEBUGGER_EVAL_PART = 14, /**< next message of evaluating a string */
|
||||
} jerry_debugger_header_type_t;
|
||||
|
||||
/**
|
||||
@ -308,7 +311,6 @@ typedef struct
|
||||
uint8_t eval_size[sizeof (uint32_t)]; /**< total size of the message */
|
||||
} jerry_debugger_receive_eval_first_t;
|
||||
|
||||
|
||||
/**
|
||||
* Incoming message: first message of client source.
|
||||
*/
|
||||
|
||||
@ -33,7 +33,8 @@ extern "C"
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED = 0, /**< source is not received */
|
||||
JERRY_DEBUGGER_SOURCE_RECEIVED = 1, /**< the source has been received */
|
||||
JERRY_DEBUGGER_SOURCE_RECEIVED = 1, /**< a source has been received */
|
||||
JERRY_DEBUGGER_SOURCE_END = 2, /**< the end of the sources signal received */
|
||||
} jerry_debugger_wait_and_run_type_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -58,6 +58,7 @@ 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;
|
||||
|
||||
// Subtypes of eval
|
||||
var JERRY_DEBUGGER_EVAL_OK = 1;
|
||||
@ -71,12 +72,13 @@ 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_CONTINUE = 8;
|
||||
var JERRY_DEBUGGER_STEP = 9;
|
||||
var JERRY_DEBUGGER_NEXT = 10;
|
||||
var JERRY_DEBUGGER_GET_BACKTRACE = 11;
|
||||
var JERRY_DEBUGGER_EVAL = 12;
|
||||
var JERRY_DEBUGGER_EVAL_PART = 13;
|
||||
var JERRY_DEBUGGER_NO_MORE_SOURCES = 8;
|
||||
var JERRY_DEBUGGER_CONTINUE = 9;
|
||||
var JERRY_DEBUGGER_STEP = 10;
|
||||
var JERRY_DEBUGGER_NEXT = 11;
|
||||
var JERRY_DEBUGGER_GET_BACKTRACE = 12;
|
||||
var JERRY_DEBUGGER_EVAL = 13;
|
||||
var JERRY_DEBUGGER_EVAL_PART = 14;
|
||||
|
||||
var textBox = document.getElementById("log");
|
||||
var commandBox = document.getElementById("command");
|
||||
@ -921,6 +923,12 @@ function DebuggerClient(address)
|
||||
return;
|
||||
}
|
||||
|
||||
case JERRY_DEBUGGER_WAIT_FOR_SOURCE:
|
||||
{
|
||||
// This message does not have effect in this client.
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
abortConnection("unexpected message.");
|
||||
|
||||
@ -48,6 +48,7 @@ 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
|
||||
|
||||
# Subtypes of eval
|
||||
JERRY_DEBUGGER_EVAL_OK = 1
|
||||
@ -62,12 +63,13 @@ JERRY_DEBUGGER_MEMSTATS = 4
|
||||
JERRY_DEBUGGER_STOP = 5
|
||||
JERRY_DEBUGGER_CLIENT_SOURCE = 6
|
||||
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7
|
||||
JERRY_DEBUGGER_CONTINUE = 8
|
||||
JERRY_DEBUGGER_STEP = 9
|
||||
JERRY_DEBUGGER_NEXT = 10
|
||||
JERRY_DEBUGGER_GET_BACKTRACE = 11
|
||||
JERRY_DEBUGGER_EVAL = 12
|
||||
JERRY_DEBUGGER_EVAL_PART = 13
|
||||
JERRY_DEBUGGER_NO_MORE_SOURCES = 8
|
||||
JERRY_DEBUGGER_CONTINUE = 9
|
||||
JERRY_DEBUGGER_STEP = 10
|
||||
JERRY_DEBUGGER_NEXT = 11
|
||||
JERRY_DEBUGGER_GET_BACKTRACE = 12
|
||||
JERRY_DEBUGGER_EVAL = 13
|
||||
JERRY_DEBUGGER_EVAL_PART = 14
|
||||
|
||||
MAX_BUFFER_SIZE = 128
|
||||
WEBSOCKET_BINARY_FRAME = 2
|
||||
@ -89,7 +91,7 @@ def arguments_parse():
|
||||
help="set display range")
|
||||
parser.add_argument("--exception", action="store", default=None, type=int, choices=[0, 1],
|
||||
help="set exception config, usage 1: [Enable] or 0: [Disable]")
|
||||
parser.add_argument("--client-source", action="store", default=None, type=str,
|
||||
parser.add_argument("--client-source", action="store", default=[], type=str, nargs="+",
|
||||
help="specify a javascript source file to execute")
|
||||
|
||||
args = parser.parse_args()
|
||||
@ -181,6 +183,7 @@ class DebuggerPrompt(Cmd):
|
||||
self.quit = False
|
||||
self.cont = True
|
||||
self.non_interactive = False
|
||||
self.client_sources = []
|
||||
|
||||
def precmd(self, line):
|
||||
self.stop = False
|
||||
@ -431,16 +434,28 @@ class DebuggerPrompt(Cmd):
|
||||
|
||||
do_ms = do_memstats
|
||||
|
||||
def send_client_source(self, args):
|
||||
""" Send and execute the specified Javascript source file to the debugger """
|
||||
if not args.lower().endswith('.js'):
|
||||
def store_client_sources(self, args):
|
||||
self.client_sources = args
|
||||
|
||||
def send_client_source(self):
|
||||
# Send no more source message if there is no source
|
||||
if not self.client_sources:
|
||||
self.send_no_more_source()
|
||||
return
|
||||
|
||||
path = self.client_sources.pop(0)
|
||||
if not path.lower().endswith('.js'):
|
||||
sys.exit("Error: Javascript file expected!")
|
||||
return
|
||||
|
||||
with open(args, 'r') as f:
|
||||
content = args + "\0" + f.read()
|
||||
with open(path, 'r') as f:
|
||||
content = path + "\0" + f.read()
|
||||
self.send_string(content, JERRY_DEBUGGER_CLIENT_SOURCE)
|
||||
|
||||
def send_no_more_source(self):
|
||||
self.exec_command("", JERRY_DEBUGGER_NO_MORE_SOURCES)
|
||||
self.cont = True
|
||||
|
||||
class Multimap(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -963,7 +978,7 @@ def main():
|
||||
prompt.do_exception(str(args.exception))
|
||||
|
||||
if args.client_source is not None:
|
||||
prompt.send_client_source(str(args.client_source))
|
||||
prompt.store_client_sources(args.client_source)
|
||||
|
||||
while True:
|
||||
if not non_interactive and prompt.cont:
|
||||
@ -1106,6 +1121,9 @@ def main():
|
||||
|
||||
prompt.cmdloop()
|
||||
|
||||
elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE:
|
||||
prompt.send_client_source()
|
||||
|
||||
else:
|
||||
raise Exception("Unknown message")
|
||||
|
||||
|
||||
@ -723,14 +723,28 @@ main (int argc,
|
||||
{
|
||||
is_repl_mode = false;
|
||||
#ifdef JERRY_DEBUGGER
|
||||
jerry_value_t wait_and_run_value;
|
||||
jerry_value_t run_result;
|
||||
jerry_debugger_wait_and_run_type_t receive_status;
|
||||
|
||||
if (jerry_debugger_wait_and_run_client_source (&wait_and_run_value) == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
do
|
||||
{
|
||||
ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "Connection aborted before source arrived.");
|
||||
}
|
||||
receive_status = jerry_debugger_wait_and_run_client_source (&run_result);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
ret_value = jerry_create_error (JERRY_ERROR_COMMON,
|
||||
(jerry_char_t *) "Connection aborted before source arrived.");
|
||||
}
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_END)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "No more client source.\n");
|
||||
}
|
||||
|
||||
jerry_release_value (run_result);
|
||||
}
|
||||
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
|
||||
jerry_release_value (wait_and_run_value);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
}
|
||||
|
||||
|
||||
7
tests/debugger/client_source_multiple.cmd
Normal file
7
tests/debugger/client_source_multiple.cmd
Normal file
@ -0,0 +1,7 @@
|
||||
n
|
||||
n
|
||||
s
|
||||
s
|
||||
s
|
||||
s
|
||||
c
|
||||
15
tests/debugger/client_source_multiple.expected
Normal file
15
tests/debugger/client_source_multiple.expected
Normal file
@ -0,0 +1,15 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/client_source_multiple_2.js:15
|
||||
(jerry-debugger) n
|
||||
Stopped at tests/debugger/client_source_multiple_1.js:15
|
||||
(jerry-debugger) n
|
||||
Stopped at tests/debugger/client_source_multiple_1.js:27
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/client_source_multiple_1.js:18 (in foo() at line:17, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/client_source_multiple_1.js:19 (in foo() at line:17, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/client_source_multiple_2.js:18 (in bar() at line:17, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/client_source_multiple_2.js:19 (in bar() at line:17, col:1)
|
||||
(jerry-debugger) c
|
||||
27
tests/debugger/client_source_multiple_1.js
Normal file
27
tests/debugger/client_source_multiple_1.js
Normal file
@ -0,0 +1,27 @@
|
||||
// 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("multiple-client-source-test-file-1");
|
||||
|
||||
function foo() {
|
||||
print("foo");
|
||||
bar("called-from-test-file-1");
|
||||
}
|
||||
|
||||
function crossFoo(str) {
|
||||
print("crossFoo");
|
||||
print("str-argument: " + str);
|
||||
}
|
||||
|
||||
foo();
|
||||
21
tests/debugger/client_source_multiple_2.js
Normal file
21
tests/debugger/client_source_multiple_2.js
Normal file
@ -0,0 +1,21 @@
|
||||
// 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("multiple-client-source-test-file-2");
|
||||
|
||||
function bar(str) {
|
||||
print("bar");
|
||||
print("str-argument: " + str);
|
||||
crossFoo("called-from-test-file-2");
|
||||
}
|
||||
@ -218,7 +218,7 @@ def run_jerry_debugger_tests(options):
|
||||
break
|
||||
|
||||
for test_file in os.listdir(settings.DEBUGGER_TESTS_DIR):
|
||||
if test_file.endswith(".js"):
|
||||
if test_file.endswith(".cmd"):
|
||||
test_case, _ = os.path.splitext(test_file)
|
||||
test_case_path = os.path.join(settings.DEBUGGER_TESTS_DIR, test_case)
|
||||
test_cmd = [
|
||||
|
||||
@ -21,7 +21,11 @@ CLIENT_ARGS=""
|
||||
|
||||
if [[ $TEST_CASE == *"client_source"* ]]; then
|
||||
START_DEBUG_SERVER="${JERRY} --start-debug-server --debugger-wait-source &"
|
||||
CLIENT_ARGS="--client-source ${TEST_CASE}.js"
|
||||
if [[ $TEST_CASE == *"client_source_multiple"* ]]; then
|
||||
CLIENT_ARGS="--client-source ${TEST_CASE}_2.js ${TEST_CASE}_1.js"
|
||||
else
|
||||
CLIENT_ARGS="--client-source ${TEST_CASE}.js"
|
||||
fi
|
||||
else
|
||||
START_DEBUG_SERVER="${JERRY} ${TEST_CASE}.js --start-debug-server &"
|
||||
fi
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user