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:
Daniel Balla 2017-08-30 16:01:06 +02:00 committed by László Langó
parent e897858c64
commit 733f0ceea0
17 changed files with 172 additions and 7 deletions

View File

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

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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:
{

View File

@ -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")

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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