Add total frame counter to backtrace in debugger (#2428)
This was needed for the VScode extension so we know in total howmany frames we have in the backtrace. JerryScript-DCO-1.0-Signed-off-by: Daniella Barsony bella@inf.u-szeged.hu
This commit is contained in:
committed by
Robert Sipka
parent
87897849f6
commit
64051b5bd8
@@ -37,9 +37,9 @@ typedef struct
|
|||||||
* The number of message types in the debugger should reflect the
|
* The number of message types in the debugger should reflect the
|
||||||
* debugger versioning.
|
* debugger versioning.
|
||||||
*/
|
*/
|
||||||
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27
|
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 28
|
||||||
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 19
|
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 19
|
||||||
&& JERRY_DEBUGGER_VERSION == 4,
|
&& JERRY_DEBUGGER_VERSION == 5,
|
||||||
debugger_version_correlates_to_message_type_count);
|
debugger_version_correlates_to_message_type_count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,6 +120,23 @@ jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the
|
|||||||
max_depth = UINT32_MAX;
|
max_depth = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_backtrace_p->get_total_frame_count != 0)
|
||||||
|
{
|
||||||
|
JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_total_t, backtrace_total_p);
|
||||||
|
backtrace_total_p->type = JERRY_DEBUGGER_BACKTRACE_TOTAL;
|
||||||
|
|
||||||
|
vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
|
||||||
|
uint32_t frame_count = 0;
|
||||||
|
while (iter_frame_ctx_p != NULL)
|
||||||
|
{
|
||||||
|
frame_count++;
|
||||||
|
iter_frame_ctx_p = iter_frame_ctx_p->prev_context_p;
|
||||||
|
}
|
||||||
|
memcpy (backtrace_total_p->frame_count, &frame_count, sizeof (frame_count));
|
||||||
|
|
||||||
|
jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + sizeof (frame_count));
|
||||||
|
}
|
||||||
|
|
||||||
JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_t, backtrace_p);
|
JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_t, backtrace_p);
|
||||||
|
|
||||||
backtrace_p->type = JERRY_DEBUGGER_BACKTRACE;
|
backtrace_p->type = JERRY_DEBUGGER_BACKTRACE;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
/**
|
/**
|
||||||
* JerryScript debugger protocol version.
|
* JerryScript debugger protocol version.
|
||||||
*/
|
*/
|
||||||
#define JERRY_DEBUGGER_VERSION (4)
|
#define JERRY_DEBUGGER_VERSION (5)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frequency of calling jerry_debugger_receive() by the VM.
|
* Frequency of calling jerry_debugger_receive() by the VM.
|
||||||
@@ -149,13 +149,14 @@ typedef enum
|
|||||||
JERRY_DEBUGGER_EXCEPTION_HIT = 17, /**< notify exception hit */
|
JERRY_DEBUGGER_EXCEPTION_HIT = 17, /**< notify exception hit */
|
||||||
JERRY_DEBUGGER_EXCEPTION_STR = 18, /**< exception string fragment */
|
JERRY_DEBUGGER_EXCEPTION_STR = 18, /**< exception string fragment */
|
||||||
JERRY_DEBUGGER_EXCEPTION_STR_END = 19, /**< exception string last fragment */
|
JERRY_DEBUGGER_EXCEPTION_STR_END = 19, /**< exception string last fragment */
|
||||||
JERRY_DEBUGGER_BACKTRACE = 20, /**< backtrace data */
|
JERRY_DEBUGGER_BACKTRACE_TOTAL = 20, /**< number of total frames */
|
||||||
JERRY_DEBUGGER_BACKTRACE_END = 21, /**< last backtrace data */
|
JERRY_DEBUGGER_BACKTRACE = 21, /**< backtrace data */
|
||||||
JERRY_DEBUGGER_EVAL_RESULT = 22, /**< eval result */
|
JERRY_DEBUGGER_BACKTRACE_END = 22, /**< last backtrace data */
|
||||||
JERRY_DEBUGGER_EVAL_RESULT_END = 23, /**< last part of eval result */
|
JERRY_DEBUGGER_EVAL_RESULT = 23, /**< eval result */
|
||||||
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24, /**< engine waiting for source code */
|
JERRY_DEBUGGER_EVAL_RESULT_END = 24, /**< last part of eval result */
|
||||||
JERRY_DEBUGGER_OUTPUT_RESULT = 25, /**< output sent by the program to the debugger */
|
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25, /**< engine waiting for source code */
|
||||||
JERRY_DEBUGGER_OUTPUT_RESULT_END = 26, /**< last output result data */
|
JERRY_DEBUGGER_OUTPUT_RESULT = 26, /**< output sent by the program to the debugger */
|
||||||
|
JERRY_DEBUGGER_OUTPUT_RESULT_END = 27, /**< last output result data */
|
||||||
|
|
||||||
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
|
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
|
||||||
|
|
||||||
@@ -356,6 +357,15 @@ typedef struct
|
|||||||
jerry_debugger_frame_t frames[]; /**< frames */
|
jerry_debugger_frame_t frames[]; /**< frames */
|
||||||
} jerry_debugger_send_backtrace_t;
|
} jerry_debugger_send_backtrace_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing message: number of total frames in backtrace.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t type; /**< type of the message */
|
||||||
|
uint8_t frame_count[sizeof (uint32_t)]; /**< total number of frames*/
|
||||||
|
} jerry_debugger_send_backtrace_total_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incoming message: set behaviour when exception occures.
|
* Incoming message: set behaviour when exception occures.
|
||||||
*/
|
*/
|
||||||
@@ -382,6 +392,7 @@ typedef struct
|
|||||||
uint8_t type; /**< type of the message */
|
uint8_t type; /**< type of the message */
|
||||||
uint8_t min_depth[sizeof (uint32_t)]; /**< minimum depth*/
|
uint8_t min_depth[sizeof (uint32_t)]; /**< minimum depth*/
|
||||||
uint8_t max_depth[sizeof (uint32_t)]; /**< maximum depth (0 - unlimited) */
|
uint8_t max_depth[sizeof (uint32_t)]; /**< maximum depth (0 - unlimited) */
|
||||||
|
uint8_t get_total_frame_count; /**< non-zero: if total frame count is also requested */
|
||||||
} jerry_debugger_receive_get_backtrace_t;
|
} jerry_debugger_receive_get_backtrace_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import struct
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Expected debugger protocol version.
|
# Expected debugger protocol version.
|
||||||
JERRY_DEBUGGER_VERSION = 4
|
JERRY_DEBUGGER_VERSION = 5
|
||||||
JERRY_DEBUGGER_DATA_END = '\3'
|
JERRY_DEBUGGER_DATA_END = '\3'
|
||||||
|
|
||||||
# Messages sent by the server to client.
|
# Messages sent by the server to client.
|
||||||
@@ -47,13 +47,14 @@ JERRY_DEBUGGER_BREAKPOINT_HIT = 16
|
|||||||
JERRY_DEBUGGER_EXCEPTION_HIT = 17
|
JERRY_DEBUGGER_EXCEPTION_HIT = 17
|
||||||
JERRY_DEBUGGER_EXCEPTION_STR = 18
|
JERRY_DEBUGGER_EXCEPTION_STR = 18
|
||||||
JERRY_DEBUGGER_EXCEPTION_STR_END = 19
|
JERRY_DEBUGGER_EXCEPTION_STR_END = 19
|
||||||
JERRY_DEBUGGER_BACKTRACE = 20
|
JERRY_DEBUGGER_BACKTRACE_TOTAL = 20
|
||||||
JERRY_DEBUGGER_BACKTRACE_END = 21
|
JERRY_DEBUGGER_BACKTRACE = 21
|
||||||
JERRY_DEBUGGER_EVAL_RESULT = 22
|
JERRY_DEBUGGER_BACKTRACE_END = 22
|
||||||
JERRY_DEBUGGER_EVAL_RESULT_END = 23
|
JERRY_DEBUGGER_EVAL_RESULT = 23
|
||||||
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24
|
JERRY_DEBUGGER_EVAL_RESULT_END = 24
|
||||||
JERRY_DEBUGGER_OUTPUT_RESULT = 25
|
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25
|
||||||
JERRY_DEBUGGER_OUTPUT_RESULT_END = 26
|
JERRY_DEBUGGER_OUTPUT_RESULT = 26
|
||||||
|
JERRY_DEBUGGER_OUTPUT_RESULT_END = 27
|
||||||
|
|
||||||
# Subtypes of eval
|
# Subtypes of eval
|
||||||
JERRY_DEBUGGER_EVAL_EVAL = "\0"
|
JERRY_DEBUGGER_EVAL_EVAL = "\0"
|
||||||
@@ -276,6 +277,8 @@ class JerryDebugger(object):
|
|||||||
self.breakpoint_info = ''
|
self.breakpoint_info = ''
|
||||||
self.smessage = ''
|
self.smessage = ''
|
||||||
self.min_depth = 0
|
self.min_depth = 0
|
||||||
|
self.max_depth = 0
|
||||||
|
self.get_total = 0
|
||||||
|
|
||||||
self.send_message(b"GET /jerry-debugger HTTP/1.1\r\n" +
|
self.send_message(b"GET /jerry-debugger HTTP/1.1\r\n" +
|
||||||
b"Upgrade: websocket\r\n" +
|
b"Upgrade: websocket\r\n" +
|
||||||
@@ -451,36 +454,41 @@ class JerryDebugger(object):
|
|||||||
return DisplayData("delete", result)
|
return DisplayData("delete", result)
|
||||||
|
|
||||||
def backtrace(self, args):
|
def backtrace(self, args):
|
||||||
max_depth = 0
|
|
||||||
self.min_depth = 0
|
self.min_depth = 0
|
||||||
|
self.max_depth = 0
|
||||||
|
self.get_total = 0
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
args = args.split(" ")
|
args = args.split(" ")
|
||||||
try:
|
try:
|
||||||
|
if "t" in args:
|
||||||
|
self.get_total = 1
|
||||||
|
args = args[:-1]
|
||||||
if len(args) == 2:
|
if len(args) == 2:
|
||||||
self.min_depth = int(args[0])
|
self.min_depth = int(args[0])
|
||||||
max_depth = int(args[1])
|
self.max_depth = int(args[1])
|
||||||
if max_depth <= 0 or self.min_depth < 0:
|
if self.max_depth <= 0 or self.min_depth < 0:
|
||||||
return DisplayData("backtrace", "Error: Positive integer number expected")
|
return DisplayData("backtrace", "Error: Positive integer number expected")
|
||||||
if self.min_depth > max_depth:
|
if self.min_depth > self.max_depth:
|
||||||
return DisplayData("backtrace", "Error: Start depth needs to be lower than or equal to max" \
|
return DisplayData("backtrace", "Error: Start depth needs to be lower than or equal to max" \
|
||||||
" depth")
|
" depth")
|
||||||
|
|
||||||
else:
|
elif len(args) == 1:
|
||||||
max_depth = int(args[0])
|
self.max_depth = int(args[0])
|
||||||
if max_depth <= 0:
|
if self.max_depth <= 0:
|
||||||
return DisplayData("backtrace", "Error: Positive integer number expected")
|
return DisplayData("backtrace", "Error: Positive integer number expected")
|
||||||
|
|
||||||
except ValueError as val_errno:
|
except ValueError as val_errno:
|
||||||
return DisplayData("backtrace", "Error: Positive integer number expected, %s" % (val_errno))
|
return DisplayData("backtrace", "Error: Positive integer number expected, %s" % (val_errno))
|
||||||
|
|
||||||
message = struct.pack(self.byte_order + "BBIB" + self.idx_format + self.idx_format,
|
message = struct.pack(self.byte_order + "BBIB" + self.idx_format + self.idx_format + "B",
|
||||||
WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
|
WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
|
||||||
WEBSOCKET_FIN_BIT + 1 + 4 + 4,
|
WEBSOCKET_FIN_BIT + 1 + 4 + 4 + 1,
|
||||||
0,
|
0,
|
||||||
JERRY_DEBUGGER_GET_BACKTRACE,
|
JERRY_DEBUGGER_GET_BACKTRACE,
|
||||||
self.min_depth,
|
self.min_depth,
|
||||||
max_depth)
|
self.max_depth,
|
||||||
|
self.get_total)
|
||||||
self.send_message(message)
|
self.send_message(message)
|
||||||
|
|
||||||
def eval(self, code):
|
def eval(self, code):
|
||||||
@@ -776,16 +784,21 @@ class JerryDebugger(object):
|
|||||||
elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR_END:
|
elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR_END:
|
||||||
exception_string += data[3:]
|
exception_string += data[3:]
|
||||||
|
|
||||||
elif buffer_type in [JERRY_DEBUGGER_BACKTRACE, JERRY_DEBUGGER_BACKTRACE_END]:
|
elif buffer_type in [JERRY_DEBUGGER_BACKTRACE,
|
||||||
|
JERRY_DEBUGGER_BACKTRACE_END,
|
||||||
|
JERRY_DEBUGGER_BACKTRACE_TOTAL]:
|
||||||
if self.min_depth != 0:
|
if self.min_depth != 0:
|
||||||
frame_index = self.min_depth
|
frame_index = self.min_depth
|
||||||
else:
|
else:
|
||||||
frame_index = 0
|
frame_index = 0
|
||||||
|
|
||||||
|
total_frames = 0
|
||||||
while True:
|
while True:
|
||||||
|
if buffer_type == JERRY_DEBUGGER_BACKTRACE_TOTAL:
|
||||||
|
total_frames = struct.unpack(self.byte_order + self.idx_format, data[3:7])[0]
|
||||||
|
|
||||||
buffer_pos = 3
|
buffer_pos = 3
|
||||||
while buffer_size > 0:
|
while buffer_size > 4:
|
||||||
breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format,
|
breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format,
|
||||||
data[buffer_pos: buffer_pos + self.cp_size + 4])
|
data[buffer_pos: buffer_pos + self.cp_size + 4])
|
||||||
|
|
||||||
@@ -800,6 +813,17 @@ class JerryDebugger(object):
|
|||||||
result += '\n'
|
result += '\n'
|
||||||
|
|
||||||
if buffer_type == JERRY_DEBUGGER_BACKTRACE_END:
|
if buffer_type == JERRY_DEBUGGER_BACKTRACE_END:
|
||||||
|
if self.get_total == 1:
|
||||||
|
if self.max_depth > total_frames:
|
||||||
|
self.max_depth = total_frames
|
||||||
|
if self.max_depth == 0:
|
||||||
|
result += ("\nTotal Frames: %d" % total_frames)
|
||||||
|
elif self.min_depth != 0 and self.max_depth != 0 and \
|
||||||
|
(self.max_depth - self.min_depth) > 0:
|
||||||
|
result += ("\nGetting %d frames. There are %d in total." %
|
||||||
|
((self.max_depth - self.min_depth), total_frames))
|
||||||
|
elif self.min_depth == 0 and self.max_depth != 0:
|
||||||
|
result += ("\nGetting the first %d frames out of %d." % (self.max_depth, total_frames))
|
||||||
break
|
break
|
||||||
|
|
||||||
data = self.get_message(True)
|
data = self.get_message(True)
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ next
|
|||||||
step
|
step
|
||||||
next
|
next
|
||||||
s
|
s
|
||||||
|
bt 1 2 t
|
||||||
bt 1 2
|
bt 1 2
|
||||||
|
bt 0 3 t
|
||||||
bt
|
bt
|
||||||
bt 2
|
bt 2
|
||||||
|
bt 2 t
|
||||||
n
|
n
|
||||||
n
|
n
|
||||||
s
|
s
|
||||||
@@ -14,5 +17,6 @@ backtrace
|
|||||||
bt 4 4
|
bt 4 4
|
||||||
bt 600 919
|
bt 600 919
|
||||||
bt 3 500
|
bt 3 500
|
||||||
|
bt 42
|
||||||
bt 4 3
|
bt 4 3
|
||||||
c
|
c
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ out: function test
|
|||||||
Stopped at tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
Stopped at tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||||
(jerry-debugger) s
|
(jerry-debugger) s
|
||||||
Stopped at tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
Stopped at tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
||||||
|
(jerry-debugger) bt 1 2 t
|
||||||
|
Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||||
|
Getting 1 frames. There are 3 in total.
|
||||||
(jerry-debugger) bt 1 2
|
(jerry-debugger) bt 1 2
|
||||||
Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||||
|
(jerry-debugger) bt 0 3 t
|
||||||
|
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
|
||||||
|
Getting the first 3 frames out of 3.
|
||||||
(jerry-debugger) bt
|
(jerry-debugger) bt
|
||||||
Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
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 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||||
@@ -23,6 +31,10 @@ Frame 2: tests/debugger/do_backtrace.js:40
|
|||||||
(jerry-debugger) bt 2
|
(jerry-debugger) bt 2
|
||||||
Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
|
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 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
|
||||||
|
(jerry-debugger) bt 2 t
|
||||||
|
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)
|
||||||
|
Getting the first 2 frames out of 3.
|
||||||
(jerry-debugger) n
|
(jerry-debugger) n
|
||||||
out: function foo
|
out: function foo
|
||||||
Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1)
|
Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1)
|
||||||
@@ -39,6 +51,11 @@ Frame 3: tests/debugger/do_backtrace.js:40
|
|||||||
(jerry-debugger) bt 600 919
|
(jerry-debugger) bt 600 919
|
||||||
(jerry-debugger) bt 3 500
|
(jerry-debugger) bt 3 500
|
||||||
Frame 3: tests/debugger/do_backtrace.js:40
|
Frame 3: tests/debugger/do_backtrace.js:40
|
||||||
|
(jerry-debugger) bt 42
|
||||||
|
Frame 0: tests/debugger/do_backtrace.js:18 (in f4() at line:17, col:1)
|
||||||
|
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) bt 4 3
|
(jerry-debugger) bt 4 3
|
||||||
Error: Start depth needs to be lower than or equal to max depth
|
Error: Start depth needs to be lower than or equal to max depth
|
||||||
(jerry-debugger) c
|
(jerry-debugger) c
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ docstring-min-length=-1
|
|||||||
[ELIF]
|
[ELIF]
|
||||||
|
|
||||||
# Maximum number of nested blocks for function / method body
|
# Maximum number of nested blocks for function / method body
|
||||||
max-nested-blocks=5
|
max-nested-blocks=7
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
[LOGGING]
|
||||||
|
|||||||
Reference in New Issue
Block a user