mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Send output to debugger client (#1955)
Sending the output to the debugger client, at the moment only the JS side prints are sent over. JerryScript-DCO-1.0-Signed-off-by: Daniel Balla dballa@inf.u-szeged.hu
This commit is contained in:
parent
e897858c64
commit
733f0ceea0
@ -26,9 +26,9 @@ 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 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)
|
||||
for more than one file, right after the engine initialization
|
||||
(this feature is 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
|
||||
on a system with much more resources and it should be capable of
|
||||
storing this information. JerryScript frees all debug information
|
||||
@ -206,8 +206,8 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
|
||||
|
||||
**Summary**
|
||||
|
||||
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
|
||||
Stops the engine and puts it into a waiting loop. If the client sends
|
||||
a source code and JerryScript receives that, then the function will
|
||||
run the source with the initialized options, after that the engine will
|
||||
wait for a new source until the client send a close signal.
|
||||
|
||||
@ -232,10 +232,34 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value)
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
// Handle the fail (e.g. create an error).
|
||||
// Handle the failure (e.g. create an error).
|
||||
}
|
||||
}
|
||||
|
||||
jerry_release_value (run_result);
|
||||
}
|
||||
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
```
|
||||
|
||||
### jerry_debugger_send_output
|
||||
|
||||
**Summary**
|
||||
|
||||
Sends the program's output to the debugger client.
|
||||
At the moment only the JS print size is implemented.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t string_size, uint8_t type)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
jerry_char_t my_output = "Hey, this should be sent too!";
|
||||
jerry_size_t my_output_size = sizeof (my_output);
|
||||
|
||||
jerry_debugger_send_output (my_output, my_output_size, JERRY_DEBUGGER_OUTPUT_OK);
|
||||
```
|
||||
|
||||
@ -814,6 +814,24 @@ jerry_debugger_send_parse_function (uint32_t line, /**< line */
|
||||
return jerry_debugger_send (sizeof (jerry_debugger_send_parse_function_t));
|
||||
} /* jerry_debugger_send_parse_function */
|
||||
|
||||
/**
|
||||
* Send the output of the program to the debugger client.
|
||||
* Currently only sends print output.
|
||||
*/
|
||||
void
|
||||
jerry_debugger_send_output (jerry_char_t buffer[], /**< buffer */
|
||||
jerry_size_t str_size, /**< string size */
|
||||
uint8_t type) /**< type of output */
|
||||
{
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
{
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
|
||||
type,
|
||||
(const uint8_t *) buffer,
|
||||
sizeof (uint8_t) * str_size);
|
||||
}
|
||||
} /* jerry_debugger_send_output */
|
||||
|
||||
/**
|
||||
* Send memory statistics to the debugger client.
|
||||
*/
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "debugger-ws.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "jerryscript-core.h"
|
||||
|
||||
#ifdef JERRY_DEBUGGER
|
||||
|
||||
@ -121,6 +122,8 @@ typedef enum
|
||||
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 */
|
||||
|
||||
/* Messages sent by the client to server. */
|
||||
|
||||
@ -146,7 +149,7 @@ typedef enum
|
||||
} jerry_debugger_header_type_t;
|
||||
|
||||
/**
|
||||
* Subtypes of send_eval.
|
||||
* Subtypes of eval_result.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@ -154,6 +157,16 @@ typedef enum
|
||||
JERRY_DEBUGGER_EVAL_ERROR = 2, /**< eval result when an error is occured */
|
||||
} jerry_debugger_eval_subtype_t;
|
||||
|
||||
/**
|
||||
* Subtypes of output_result.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_OUTPUT_OK = 1, /**< output result, no error */
|
||||
JERRY_DEBUGGER_OUTPUT_WARNING = 2, /**< output result, warning */
|
||||
JERRY_DEBUGGER_OUTPUT_ERROR = 3, /**< output result, error */
|
||||
} jerry_debugger_output_subtype_t;
|
||||
|
||||
/**
|
||||
* Delayed free of byte code data.
|
||||
*/
|
||||
@ -337,6 +350,7 @@ bool jerry_debugger_send_function_cp (jerry_debugger_header_type_t type, ecma_co
|
||||
bool jerry_debugger_send_parse_function (uint32_t line, uint32_t column);
|
||||
void jerry_debugger_send_memstats (void);
|
||||
bool jerry_debugger_send_exception_string (ecma_value_t exception_value);
|
||||
void jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t str_size, uint8_t type);
|
||||
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
|
||||
|
||||
@ -59,11 +59,18 @@ 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;
|
||||
|
||||
// Subtypes of eval
|
||||
var JERRY_DEBUGGER_EVAL_OK = 1;
|
||||
var JERRY_DEBUGGER_EVAL_ERROR = 2;
|
||||
|
||||
// Subtypes of output result
|
||||
var JERRY_DEBUGGER_OUTPUT_OK = 1;
|
||||
var JERRY_DEBUGGER_OUTPUT_WARNING = 2;
|
||||
var JERRY_DEBUGGER_OUTPUT_ERROR = 3;
|
||||
|
||||
// Messages sent by the client to server.
|
||||
var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1;
|
||||
var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
|
||||
@ -123,6 +130,7 @@ function DebuggerClient(address)
|
||||
var pendingBreakpoints = [ ];
|
||||
var backtraceFrame = 0;
|
||||
var evalResult = null;
|
||||
var outputResult = null;
|
||||
var exceptionData = null;
|
||||
var display = 0;
|
||||
|
||||
@ -922,6 +930,36 @@ function DebuggerClient(address)
|
||||
|
||||
return;
|
||||
}
|
||||
case JERRY_DEBUGGER_OUTPUT_RESULT:
|
||||
case JERRY_DEBUGGER_OUTPUT_RESULT_END:
|
||||
{
|
||||
outputResult = concatUint8Arrays(outputResult, message);
|
||||
|
||||
if (message[0] == JERRY_DEBUGGER_OUTPUT_RESULT_END)
|
||||
{
|
||||
var subType = outputResult[outputResult.length - 1];
|
||||
var outString;
|
||||
outputResult = outputResult.slice(0, -1);
|
||||
|
||||
switch (subType)
|
||||
{
|
||||
case JERRY_DEBUGGER_OUTPUT_OK:
|
||||
outString = "out: " + cesu8ToString(outputResult);
|
||||
break;
|
||||
case JERRY_DEBUGGER_OUTPUT_WARNING:
|
||||
outString = "warning: " + cesu8ToString(outputResult);
|
||||
break;
|
||||
case JERRY_DEBUGGER_OUTPUT_ERROR:
|
||||
outString = "err: " + cesu8ToString(outputResult);
|
||||
break;
|
||||
}
|
||||
|
||||
appendLog(outString);
|
||||
outputResult = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case JERRY_DEBUGGER_WAIT_FOR_SOURCE:
|
||||
{
|
||||
|
||||
@ -49,11 +49,18 @@ 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
|
||||
|
||||
# Subtypes of eval
|
||||
JERRY_DEBUGGER_EVAL_OK = 1
|
||||
JERRY_DEBUGGER_EVAL_ERROR = 2
|
||||
|
||||
# Subtypes of output
|
||||
JERRY_DEBUGGER_OUTPUT_OK = 1
|
||||
JERRY_DEBUGGER_OUTPUT_WARNING = 2
|
||||
JERRY_DEBUGGER_OUTPUT_ERROR = 3
|
||||
|
||||
|
||||
# Messages sent by the client to server.
|
||||
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
|
||||
@ -511,6 +518,7 @@ class JerryDebugger(object):
|
||||
self.yellow = ''
|
||||
self.green_bg = ''
|
||||
self.yellow_bg = ''
|
||||
self.blue = ''
|
||||
self.nocolor = ''
|
||||
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.client_socket.connect((self.host, self.port))
|
||||
@ -658,6 +666,7 @@ class JerryDebugger(object):
|
||||
self.yellow = '\033[93m'
|
||||
self.green_bg = '\033[42m'
|
||||
self.yellow_bg = '\033[43m'
|
||||
self.blue = '\033[94m'
|
||||
|
||||
def get_message(self, blocking):
|
||||
# Connection was closed
|
||||
@ -1124,6 +1133,32 @@ def main():
|
||||
elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE:
|
||||
prompt.send_client_source()
|
||||
|
||||
elif buffer_type in [JERRY_DEBUGGER_OUTPUT_RESULT, JERRY_DEBUGGER_OUTPUT_RESULT_END]:
|
||||
message = ""
|
||||
msg_type = buffer_type
|
||||
while True:
|
||||
if buffer_type == JERRY_DEBUGGER_OUTPUT_RESULT_END:
|
||||
subtype = ord(data[-1])
|
||||
message += data[3:-1]
|
||||
break
|
||||
else:
|
||||
message += data[3:]
|
||||
|
||||
data = debugger.get_message(True)
|
||||
buffer_type = ord(data[2])
|
||||
buffer_size = ord(data[1]) - 1
|
||||
|
||||
if buffer_type not in [msg_type, msg_type + 1]:
|
||||
raise Exception("Output data expected")
|
||||
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_OK:
|
||||
print("%sout: %s%s" % (debugger.blue, debugger.nocolor, message))
|
||||
elif subtype == JERRY_DEBUGGER_OUTPUT_WARNING:
|
||||
print("%swarning: %s%s" % (debugger.yellow, debugger.nocolor, message))
|
||||
elif subtype == JERRY_DEBUGGER_OUTPUT_ERROR:
|
||||
print("%serr: %s%s" % (debugger.red, debugger.nocolor, message))
|
||||
|
||||
|
||||
else:
|
||||
raise Exception("Unknown message")
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "debugger.h"
|
||||
|
||||
/**
|
||||
* Provide a 'print' implementation for scripts.
|
||||
@ -70,6 +71,9 @@ jerryx_handler_print (const jerry_value_t func_obj_val, /**< function object */
|
||||
substr_buf,
|
||||
256)) != 0)
|
||||
{
|
||||
#ifdef JERRY_DEBUGGER
|
||||
jerry_debugger_send_output (substr_buf, substr_size, JERRY_DEBUGGER_OUTPUT_OK);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
for (jerry_size_t chr_index = 0; chr_index < substr_size; chr_index++)
|
||||
{
|
||||
char chr = (char) substr_buf[chr_index];
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/client_source.js:15
|
||||
(jerry-debugger) s
|
||||
out: client-source-test
|
||||
Stopped at tests/debugger/client_source.js:40
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/client_source.js:35 (in test() at line:33, col:1)
|
||||
(jerry-debugger) s
|
||||
out: function test
|
||||
Stopped at tests/debugger/client_source.js:36 (in test() at line:33, col:1)
|
||||
(jerry-debugger) continue
|
||||
out: function foo
|
||||
out: function bar
|
||||
out: function finish
|
||||
out: finish: test-foo-bar
|
||||
|
||||
@ -1,15 +1,22 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/client_source_multiple_2.js:15
|
||||
(jerry-debugger) n
|
||||
out: multiple-client-source-test-file-2
|
||||
Stopped at tests/debugger/client_source_multiple_1.js:15
|
||||
(jerry-debugger) n
|
||||
out: multiple-client-source-test-file-1
|
||||
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
|
||||
out: foo
|
||||
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
|
||||
out: bar
|
||||
Stopped at tests/debugger/client_source_multiple_2.js:19 (in bar() at line:17, col:1)
|
||||
(jerry-debugger) c
|
||||
out: str-argument: called-from-test-file-1
|
||||
out: crossFoo
|
||||
out: str-argument: called-from-test-file-2
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_backtrace.js:15
|
||||
(jerry-debugger) next
|
||||
out: backtrace-test
|
||||
Stopped at tests/debugger/do_backtrace.js:28
|
||||
(jerry-debugger) n
|
||||
Stopped at tests/debugger/do_backtrace.js:37
|
||||
@ -9,6 +10,7 @@ Stopped at tests/debugger/do_backtrace.js:40
|
||||
(jerry-debugger) step
|
||||
Stopped at tests/debugger/do_backtrace.js:32 (in test() at line:30, col:1)
|
||||
(jerry-debugger) next
|
||||
out: function test
|
||||
Stopped at tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
||||
@ -17,6 +19,7 @@ Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
||||
Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||
Frame 2: tests/debugger/do_backtrace.js:40
|
||||
(jerry-debugger) n
|
||||
out: function foo
|
||||
Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1)
|
||||
(jerry-debugger) n
|
||||
Stopped at tests/debugger/do_backtrace.js:25 (in foo() at line:21, col:1)
|
||||
@ -28,3 +31,4 @@ Frame 1: tests/debugger/do_backtrace.js:25 (in foo() at line:21, col:1)
|
||||
Frame 2: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||
Frame 3: tests/debugger/do_backtrace.js:40
|
||||
(jerry-debugger) c
|
||||
out: function f4
|
||||
|
||||
@ -14,6 +14,8 @@ Breakpoint 4 at tests/debugger/do_break.js:45 (in f() at line:43, col:1)
|
||||
3: tests/debugger/do_break.js:33 (in f() at line:31, col:3)
|
||||
4: tests/debugger/do_break.js:45 (in f() at line:43, col:1)
|
||||
(jerry-debugger) c
|
||||
out: break test
|
||||
out: var cat
|
||||
Stopped at breakpoint:1 tests/debugger/do_break.js:51
|
||||
(jerry-debugger) delete 1
|
||||
(jerry-debugger) list
|
||||
@ -24,5 +26,6 @@ Stopped at breakpoint:1 tests/debugger/do_break.js:51
|
||||
(jerry-debugger) c
|
||||
Stopped at breakpoint:2 tests/debugger/do_break.js:36 (in test() at line:20, col:1)
|
||||
(jerry-debugger) continue
|
||||
out: function test
|
||||
Stopped at breakpoint:3 tests/debugger/do_break.js:33 (in f() at line:31, col:3)
|
||||
(jerry-debugger) c
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_delete.js:15
|
||||
(jerry-debugger) next
|
||||
out: delete tests
|
||||
Stopped at tests/debugger/do_delete.js:17
|
||||
(jerry-debugger) b do_delete.js:17
|
||||
Breakpoint 1 at tests/debugger/do_delete.js:17
|
||||
|
||||
@ -14,6 +14,7 @@ Non-negative integer number expected, 0 turns off this function
|
||||
Stopped at breakpoint:1 tests/debugger/do_display.js:15 (in a() at line:15, col:1)
|
||||
(jerry-debugger) display 2
|
||||
(jerry-debugger) c
|
||||
out: hi
|
||||
Stopped at breakpoint:2 tests/debugger/do_display.js:16 (in b() at line:16, col:1)
|
||||
Source: tests/debugger/do_display.js
|
||||
15 function a() { print("hi"); }
|
||||
@ -21,6 +22,7 @@ Source: tests/debugger/do_display.js
|
||||
17 function c() { print("hello"); }
|
||||
(jerry-debugger) display 5435
|
||||
(jerry-debugger) c
|
||||
out: welcome
|
||||
Stopped at breakpoint:3 tests/debugger/do_display.js:17 (in c() at line:17, col:1)
|
||||
Source: tests/debugger/do_display.js
|
||||
1 // Copyright JS Foundation and other contributors, http://js.foundation
|
||||
@ -48,5 +50,7 @@ Source: tests/debugger/do_display.js
|
||||
23 d();
|
||||
(jerry-debugger) display 0
|
||||
(jerry-debugger) c
|
||||
out: hello
|
||||
Stopped at breakpoint:4 tests/debugger/do_display.js:18 (in d() at line:18, col:1)
|
||||
(jerry-debugger) c
|
||||
out: goodbye
|
||||
|
||||
@ -5,3 +5,4 @@ Stopped at tests/debugger/do_eval_syntax.js:26
|
||||
(jerry-debugger) eval loop
|
||||
Uncaught exception: Error
|
||||
(jerry-debugger) c
|
||||
out: bar function
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_exception.js:15
|
||||
(jerry-debugger) c
|
||||
out: exception handler configuration test
|
||||
Exception throw detected (to disable automatic stop type exception 0)
|
||||
Exception hint: TypeError
|
||||
Stopped around tests/debugger/do_exception.js:19 (in foo() at line:17, col:1)
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_next.js:15
|
||||
(jerry-debugger) next
|
||||
out: next test
|
||||
Stopped at tests/debugger/do_next.js:17
|
||||
(jerry-debugger) next
|
||||
out: var cat
|
||||
Stopped at tests/debugger/do_next.js:18
|
||||
(jerry-debugger) c
|
||||
|
||||
@ -7,6 +7,7 @@ Pending breakpoint at f()
|
||||
=== Pending breakpoints ===
|
||||
1: f() (pending)
|
||||
(jerry-debugger) n
|
||||
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)
|
||||
|
||||
@ -5,6 +5,7 @@ Breakpoint 1 at tests/debugger/do_src.js:16 (in f() at line:15, col:1)
|
||||
(jerry-debugger) n
|
||||
Stopped at breakpoint:1 tests/debugger/do_src.js:16 (in f() at line:15, col:1)
|
||||
(jerry-debugger) next
|
||||
out: F1
|
||||
Stopped at tests/debugger/do_src.js:20
|
||||
(jerry-debugger) s
|
||||
Stopped at <unknown>:1
|
||||
@ -16,3 +17,4 @@ Stopped at tests/debugger/do_src.js:21
|
||||
Stopped at <unknown>:2 (in f() at line:1, col:5)
|
||||
(jerry-debugger) src
|
||||
(jerry-debugger) c
|
||||
out: F2
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user