diff --git a/jerry-core/debugger/debugger.h b/jerry-core/debugger/debugger.h index c31b6bf9e..ff5a37aa5 100644 --- a/jerry-core/debugger/debugger.h +++ b/jerry-core/debugger/debugger.h @@ -367,7 +367,7 @@ typedef struct typedef struct { uint8_t type; /**< type of the message */ - uint8_t frame_count[sizeof (uint32_t)]; /**< total number of frames*/ + uint8_t frame_count[sizeof (uint32_t)]; /**< total number of frames */ } jerry_debugger_send_backtrace_total_t; /** diff --git a/jerry-debugger/jerry_client.py b/jerry-debugger/jerry_client.py index f5fd136a3..7e34b69c9 100755 --- a/jerry-debugger/jerry_client.py +++ b/jerry-debugger/jerry_client.py @@ -24,6 +24,9 @@ import logging import time import jerry_client_ws +def write(string): + print(string, end='') + class DebuggerPrompt(Cmd): # pylint: disable=too-many-instance-attributes,too-many-arguments def __init__(self, debugger): @@ -31,8 +34,6 @@ class DebuggerPrompt(Cmd): self.debugger = debugger self.stop = False self.quit = False - self.backtrace = True - self.debugger.non_interactive = False def precmd(self, line): self.stop = False @@ -60,54 +61,49 @@ class DebuggerPrompt(Cmd): def do_break(self, args): """ Insert breakpoints on the given lines or functions """ - result = "" - result = self.debugger.set_break(args) - if self.debugger.not_empty(result): - print(result.get_data()) + write(self.debugger.set_break(args)) do_b = do_break def do_list(self, _): """ Lists the available breakpoints """ - result = self.debugger.show_breakpoint_list() - print(result.get_data()) + write(self.debugger.breakpoint_list()) def do_delete(self, args): """ Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints """ - result = self.debugger.delete(args) - if self.debugger.not_empty(result): - print(result.get_data()) + write(self.debugger.delete(args)) def do_next(self, args): """ Next breakpoint in the same context """ self.stop = True - if self.debugger.check_empty_data(args): + if not args: args = 0 self.debugger.next() - else: - try: - args = int(args) - if args <= 0: - raise ValueError(args) - else: - while int(args) != 0: - self.debugger.next() - time.sleep(0.5) - result = self.debugger.mainloop().get_data() - if result.endswith('\n'): - result = result.rstrip() - if jerry_client_ws.JERRY_DEBUGGER_DATA_END in result: - result = result.replace(jerry_client_ws.JERRY_DEBUGGER_DATA_END, '') - if result: - print(result) - self.debugger.smessage = '' - if self.debugger.display > 0: - print(self.debugger.print_source(self.debugger.display, - self.debugger.src_offset).get_data()) - args = int(args) - 1 - self.cmdloop() - except ValueError as val_errno: - print("Error: expected a positive integer: %s" % val_errno) - self.cmdloop() + return + + try: + args = int(args) + if args <= 0: + raise ValueError(args) + + while args > 0: + self.debugger.next() + time.sleep(0.1) + + while True: + result = self.debugger.process_messages() + res_type = result.get_type() + + if res_type == result.END: + self.quit = True + return + elif res_type == result.TEXT: + write(result.get_text()) + elif res_type == result.PROMPT: + break + + args -= 1 + except ValueError as val_errno: + print("Error: expected a positive integer: %s" % val_errno) do_n = do_next def do_step(self, _): @@ -118,14 +114,8 @@ class DebuggerPrompt(Cmd): def do_backtrace(self, args): """ Get backtrace data from debugger """ - result = self.debugger.backtrace(args) - if self.debugger.not_empty(result): - print(result.get_data()) - self.stop = True - self.cmdloop() - else: - self.stop = True - self.backtrace = True + write(self.debugger.backtrace(args)) + self.stop = True do_bt = do_backtrace def do_src(self, args): @@ -133,7 +123,7 @@ class DebuggerPrompt(Cmd): if args: line_num = src_check_args(args) if line_num >= 0: - print(self.debugger.print_source(line_num, 0).get_data()) + write(self.debugger.print_source(line_num, 0)) do_source = do_src def do_scroll(self, _): @@ -153,7 +143,7 @@ class DebuggerPrompt(Cmd): """ Continue execution """ self.debugger.get_continue() self.stop = True - if self.debugger.check_empty_data(self.debugger.non_interactive): + if not self.debugger.non_interactive: print("Press enter to stop JavaScript execution.") do_c = do_continue @@ -200,8 +190,7 @@ class DebuggerPrompt(Cmd): def do_exception(self, args): """ Config the exception handler module """ - result = self.debugger.exception(args) - print(result.get_data()) + write(self.debugger.exception(args)) def _scroll_direction(debugger, direction): """ Helper function for do_scroll """ @@ -229,66 +218,41 @@ def main(): args = jerry_client_ws.arguments_parse() debugger = jerry_client_ws.JerryDebugger(args.address) + debugger.non_interactive = args.non_interactive logging.debug("Connected to JerryScript on %d port", debugger.port) prompt = DebuggerPrompt(debugger) prompt.prompt = "(jerry-debugger) " - prompt.debugger.non_interactive = args.non_interactive if args.color: debugger.set_colors() if args.display: - prompt.debugger.display = args.display + debugger.display = args.display prompt.do_display(args.display) else: prompt.stop = False - if prompt.debugger.check_empty_data(args.client_source): - prompt.debugger.mainloop() - result = prompt.debugger.smessage - print(result) - prompt.debugger.smessage = '' - prompt.cmdloop() - if prompt.debugger.not_empty(args.exception): + if args.exception is not None: prompt.do_exception(str(args.exception)) if args.client_source: - prompt.debugger.store_client_sources(args.client_source) + debugger.store_client_sources(args.client_source) while True: if prompt.quit: break - result = prompt.debugger.mainloop().get_data() + result = debugger.process_messages() + res_type = result.get_type() - if prompt.debugger.check_empty_data(result) and prompt.backtrace is False: + if res_type == result.END: break - - if prompt.debugger.wait_data(result): - continue - - elif jerry_client_ws.JERRY_DEBUGGER_DATA_END in result: - result = result.replace(jerry_client_ws.JERRY_DEBUGGER_DATA_END, '') - if result.endswith('\n'): - result = result.rstrip() - if result: - print(result) - prompt.debugger.smessage = '' - if prompt.debugger.display > 0: - print(prompt.debugger.print_source(prompt.debugger.display, prompt.debugger.src_offset).get_data()) - prompt.backtrace = False - break - else: - if result.endswith('\n'): - result = result.rstrip() - if result: - print(result) - prompt.debugger.smessage = '' - if prompt.debugger.display > 0: - print(prompt.debugger.print_source(prompt.debugger.display, prompt.debugger.src_offset).get_data()) - prompt.cmdloop() + elif res_type == result.PROMPT: + prompt.cmdloop() + elif res_type == result.TEXT: + write(result.get_text()) continue if __name__ == "__main__": diff --git a/jerry-debugger/jerry_client_ws.py b/jerry-debugger/jerry_client_ws.py old mode 100755 new mode 100644 index 55f42b3c6..3d2aaaf20 --- a/jerry-debugger/jerry_client_ws.py +++ b/jerry-debugger/jerry_client_ws.py @@ -225,17 +225,21 @@ class Multimap(object): return "Multimap(%r)" % (self.map) -class DisplayData(object): +class DebuggerAction(object): + END = 0 + WAIT = 1 + TEXT = 2 + PROMPT = 3 - def __init__(self, stype, sdata): - self.stype = stype - self.sdata = sdata + def __init__(self, action_type, action_text): + self.action_type = action_type + self.action_text = action_text def get_type(self): - return self.stype + return self.action_type - def get_data(self): - return self.sdata + def get_text(self): + return self.action_text class JerryDebugger(object): @@ -252,9 +256,12 @@ class JerryDebugger(object): print("Connecting to: %s:%s" % (self.host, self.port)) self.message_data = b"" + self.prompt = False self.function_list = {} self.source = '' self.source_name = '' + self.exception_string = '' + self.frame_index = 0 self.client_sources = [] self.last_breakpoint_hit = None self.next_breakpoint_index = 0 @@ -274,11 +281,6 @@ class JerryDebugger(object): self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client_socket.connect((self.host, self.port)) self.non_interactive = False - self.breakpoint_info = '' - self.smessage = '' - self.min_depth = 0 - self.max_depth = 0 - self.get_total = 0 self.send_message(b"GET /jerry-debugger HTTP/1.1\r\n" + b"Upgrade: websocket\r\n" + @@ -363,53 +365,53 @@ class JerryDebugger(object): self.send_command(command_id) def quit(self): - self._exec_command(JERRY_DEBUGGER_CONTINUE) - - def get_continue(self): + self.prompt = False self._exec_command(JERRY_DEBUGGER_CONTINUE) def stop(self): self.send_command(JERRY_DEBUGGER_STOP) + def get_continue(self): + self.prompt = False + self._exec_command(JERRY_DEBUGGER_CONTINUE) + def finish(self): + self.prompt = False self._exec_command(JERRY_DEBUGGER_FINISH) def next(self): + self.prompt = False self._exec_command(JERRY_DEBUGGER_NEXT) def step(self): + self.prompt = False self._exec_command(JERRY_DEBUGGER_STEP) def memstats(self): + self.prompt = False self._exec_command(JERRY_DEBUGGER_MEMSTATS) def set_break(self, args): - if args == "": - return DisplayData("break", "Error: Breakpoint index expected") - elif ':' in args: - try: - args_second = int(args.split(':', 1)[1]) - if args_second < 0: - return DisplayData("break", "Error: Positive breakpoint index expected") - else: - _set_breakpoint(self, args, False) - except ValueError as val_errno: - return DisplayData("break", "Positive breakpoint index expected: %s" % val_errno) - else: - _set_breakpoint(self, args, False) - if self.breakpoint_info == '': - return None + if not args: + return "Error: Breakpoint index expected" - sbp = self.breakpoint_info - self.breakpoint_info = '' - return DisplayData("break", sbp) + if ':' in args: + try: + if int(args.split(':', 1)[1]) <= 0: + return "Error: Positive breakpoint index expected" + + return _set_breakpoint(self, args, False) + + except ValueError as val_errno: + return "Error: Positive breakpoint index expected: %s" % (val_errno) + + return _set_breakpoint(self, args, False) def delete(self, args): if not args: - result = "Error: Breakpoint index expected\n" \ - "Delete the given breakpoint, use 'delete all|active|pending' \ - to clear all the given breakpoints " - return DisplayData("delete", result) + return "Error: Breakpoint index expected\n" \ + "Delete the given breakpoint, use 'delete all|active|pending' " \ + "to clear all the given breakpoints\n " elif args in ['all', 'pending', 'active']: if args == "all": self.delete_active() @@ -418,25 +420,28 @@ class JerryDebugger(object): self.delete_pending() elif args == "active": self.delete_active() + return "" + + try: + breakpoint_index = int(args) + except ValueError as val_errno: + return "Error: Integer number expected, %s\n" % (val_errno) + + if breakpoint_index in self.active_breakpoint_list: + breakpoint = self.active_breakpoint_list[breakpoint_index] + del self.active_breakpoint_list[breakpoint_index] + breakpoint.active_index = -1 + self.send_breakpoint(breakpoint) + return "Breakpoint %d deleted\n" % (breakpoint_index) + elif breakpoint_index in self.pending_breakpoint_list: + del self.pending_breakpoint_list[breakpoint_index] + if not self.pending_breakpoint_list: + self.send_parser_config(0) + return "Pending breakpoint %d deleted\n" % (breakpoint_index) else: - try: - breakpoint_index = int(args) - except ValueError as val_errno: - return DisplayData("delete", "Error: Integer number expected, %s" % (val_errno)) + return "Error: Breakpoint %d not found\n" % (breakpoint_index) - if breakpoint_index in self.active_breakpoint_list: - breakpoint = self.active_breakpoint_list[breakpoint_index] - del self.active_breakpoint_list[breakpoint_index] - breakpoint.active_index = -1 - self.send_breakpoint(breakpoint) - elif breakpoint_index in self.pending_breakpoint_list: - del self.pending_breakpoint_list[breakpoint_index] - if not self.pending_breakpoint_list: - self.send_parser_config(0) - else: - return DisplayData("delete", "Error: Breakpoint %d not found" % (breakpoint_index)) - - def show_breakpoint_list(self): + def breakpoint_list(self): result = '' if self.active_breakpoint_list: result += "=== %sActive breakpoints %s ===\n" % (self.green_bg, self.nocolor) @@ -448,82 +453,87 @@ class JerryDebugger(object): result += " %d: %s (pending)\n" % (breakpoint.index, breakpoint) if not self.active_breakpoint_list and not self.pending_breakpoint_list: - result += "No breakpoints" - if result[-1:] == '\n': - result = result[:-1] - return DisplayData("delete", result) + result += "No breakpoints\n" + + return result def backtrace(self, args): - self.min_depth = 0 - self.max_depth = 0 - self.get_total = 0 + max_depth = 0 + min_depth = 0 + get_total = 0 if args: args = args.split(" ") try: if "t" in args: - self.get_total = 1 - args = args[:-1] - if len(args) == 2: - self.min_depth = int(args[0]) - self.max_depth = int(args[1]) - if self.max_depth <= 0 or self.min_depth < 0: - return DisplayData("backtrace", "Error: Positive integer number expected") - if self.min_depth > self.max_depth: - return DisplayData("backtrace", "Error: Start depth needs to be lower than or equal to max" \ - " depth") + get_total = 1 + args.remove("t") - elif len(args) == 1: - self.max_depth = int(args[0]) - if self.max_depth <= 0: - return DisplayData("backtrace", "Error: Positive integer number expected") + if len(args) >= 2: + min_depth = int(args[0]) + max_depth = int(args[1]) + if max_depth <= 0 or min_depth < 0: + return "Error: Positive integer number expected\n" + if min_depth > max_depth: + return "Error: Start depth needs to be lower than or equal to max depth\n" + elif len(args) >= 1: + max_depth = int(args[0]) + if max_depth <= 0: + return "Error: Positive integer number expected\n" except ValueError as val_errno: - return DisplayData("backtrace", "Error: Positive integer number expected, %s" % (val_errno)) + return "Error: Positive integer number expected, %s\n" % (val_errno) - message = struct.pack(self.byte_order + "BBIB" + self.idx_format + self.idx_format + "B", + self.frame_index = min_depth + message = struct.pack(self.byte_order + "BBIB" + self.idx_format + self.idx_format + "B", WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT, WEBSOCKET_FIN_BIT + 1 + 4 + 4 + 1, 0, JERRY_DEBUGGER_GET_BACKTRACE, - self.min_depth, - self.max_depth, - self.get_total) + min_depth, + max_depth, + get_total) self.send_message(message) + self.prompt = False + return "" def eval(self, code): self._send_string(JERRY_DEBUGGER_EVAL_EVAL + code, JERRY_DEBUGGER_EVAL) + self.prompt = False def throw(self, code): self._send_string(JERRY_DEBUGGER_EVAL_THROW + code, JERRY_DEBUGGER_EVAL) + self.prompt = False def abort(self, args): self.delete("all") self.exception("0") # disable the exception handler self._send_string(JERRY_DEBUGGER_EVAL_ABORT + args, JERRY_DEBUGGER_EVAL) + self.prompt = False def restart(self): self._send_string(JERRY_DEBUGGER_EVAL_ABORT + "\"r353t\"", JERRY_DEBUGGER_EVAL) + self.prompt = False def exception(self, args): try: enabled = int(args) - except (ValueError, TypeError) as val_errno: - return DisplayData("exception", "Error: Positive integer number expected, %s" % (val_errno)) + except (ValueError, TypeError): + enabled = -1 if enabled not in [0, 1]: - return DisplayData("delete", "Error: Invalid input! Usage 1: [Enable] or 0: [Disable].") + return "Error: Invalid input! Usage 1: [Enable] or 0: [Disable]\n" if enabled: logging.debug("Stop at exception enabled") self.send_exception_config(enabled) - return DisplayData("exception", "Stop at exception enabled") + return "Stop at exception enabled\n" logging.debug("Stop at exception disabled") self.send_exception_config(enabled) - return DisplayData("exception", "Stop at exception disabled") + return "Stop at exception disabled\n" def _send_string(self, args, message_type): size = len(args) @@ -705,10 +715,9 @@ class JerryDebugger(object): def send_no_more_source(self): self._exec_command(JERRY_DEBUGGER_NO_MORE_SOURCES) - # pylint: disable=too-many-branches,too-many-locals,too-many-statements - def mainloop(self): - result = '' - exception_string = "" + # pylint: disable=too-many-branches,too-many-locals,too-many-statements,too-many-return-statements + def process_messages(self): + result = "" while True: data = self.get_message(False) @@ -717,17 +726,13 @@ class JerryDebugger(object): if sys.stdin in select.select([sys.stdin], [], [], 0)[0]: sys.stdin.readline() self.stop() - continue if data == b'': - continue + action_type = DebuggerAction.PROMPT if self.prompt else DebuggerAction.WAIT + return DebuggerAction(action_type, "") if not data: # Break the while loop if there is no more data. - if result[-1:] == '\n': - result = result[:-1] - result += JERRY_DEBUGGER_DATA_END - self.smessage = result - return DisplayData("EOF", self.smessage) + return DebuggerAction(DebuggerAction.END, "") buffer_type = ord(data[2]) buffer_size = ord(data[1]) - 1 @@ -744,7 +749,9 @@ class JerryDebugger(object): JERRY_DEBUGGER_SOURCE_CODE_NAME_END, JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]: - _parse_source(self, data) + result = _parse_source(self, data) + if result: + return DebuggerAction(DebuggerAction.TEXT, result) elif buffer_type == JERRY_DEBUGGER_WAITING_AFTER_PARSE: self.send_command(JERRY_DEBUGGER_PARSER_RESUME) @@ -760,9 +767,9 @@ class JerryDebugger(object): if buffer_type == JERRY_DEBUGGER_EXCEPTION_HIT: result += "Exception throw detected (to disable automatic stop type exception 0)\n" - if exception_string: - result += "Exception hint: %s\n" % (exception_string) - exception_string = "" + if self.exception_string: + result += "Exception hint: %s\n" % (self.exception_string) + self.exception_string = "" if breakpoint[1]: breakpoint_info = "at" @@ -771,70 +778,48 @@ class JerryDebugger(object): if breakpoint[0].active_index >= 0: breakpoint_info += " breakpoint:%s%d%s" % (self.red, breakpoint[0].active_index, self.nocolor) - if self.breakpoint_info != '': - result += self.breakpoint_info + '\n' - self.breakpoint_info = '' - result += "Stopped %s %s" % (breakpoint_info, breakpoint[0]) - self.smessage = result - return DisplayData("break/exception", self.smessage) + + result += "Stopped %s %s\n" % (breakpoint_info, breakpoint[0]) + + if self.display > 0: + result += self.print_source(self.display, self.src_offset) + + self.prompt = True + return DebuggerAction(DebuggerAction.TEXT, result) elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR: - exception_string += data[3:] + self.exception_string += data[3:] elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR_END: - exception_string += data[3:] + self.exception_string += data[3:] - elif buffer_type in [JERRY_DEBUGGER_BACKTRACE, - JERRY_DEBUGGER_BACKTRACE_END, - JERRY_DEBUGGER_BACKTRACE_TOTAL]: - if self.min_depth != 0: - frame_index = self.min_depth + elif buffer_type == JERRY_DEBUGGER_BACKTRACE_TOTAL: + total = struct.unpack(self.byte_order + self.idx_format, data[3:])[0] + result += "Total number of frames: %d\n" % (total) + return DebuggerAction(DebuggerAction.TEXT, result) + + elif buffer_type in [JERRY_DEBUGGER_BACKTRACE, JERRY_DEBUGGER_BACKTRACE_END]: + frame_index = self.frame_index + + buffer_pos = 3 + while buffer_size > 0: + breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format, + data[buffer_pos: buffer_pos + self.cp_size + 4]) + + breakpoint = _get_breakpoint(self, breakpoint_data) + + result += "Frame %d: %s\n" % (frame_index, breakpoint[0]) + + frame_index += 1 + buffer_pos += 6 + buffer_size -= 6 + + if buffer_type == JERRY_DEBUGGER_BACKTRACE_END: + self.prompt = True else: - frame_index = 0 + self.frame_index = frame_index - total_frames = 0 - 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 - while buffer_size > 4: - breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format, - data[buffer_pos: buffer_pos + self.cp_size + 4]) - - breakpoint = _get_breakpoint(self, breakpoint_data) - - result += "Frame %d: %s" % (frame_index, breakpoint[0]) - - frame_index += 1 - buffer_pos += 6 - buffer_size -= 6 - if buffer_size > 0: - result += '\n' - - 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 - - data = self.get_message(True) - buffer_type = ord(data[2]) - buffer_size = ord(data[1]) - 1 - - if buffer_type not in [JERRY_DEBUGGER_BACKTRACE, - JERRY_DEBUGGER_BACKTRACE_END]: - raise Exception("Backtrace data expected") - self.smessage = result - return DisplayData("backtrace", self.smessage) + return DebuggerAction(DebuggerAction.TEXT, result) elif buffer_type in [JERRY_DEBUGGER_EVAL_RESULT, JERRY_DEBUGGER_EVAL_RESULT_END, @@ -859,31 +844,35 @@ class JerryDebugger(object): if buffer_type not in [msg_type, msg_type + 1]: raise Exception("Invalid data caught") + if not message.endswith("\n"): + message += "\n" + # Subtypes of output if buffer_type == JERRY_DEBUGGER_OUTPUT_RESULT_END: - message = message.rstrip('\n') if subtype in [JERRY_DEBUGGER_OUTPUT_OK, JERRY_DEBUGGER_OUTPUT_DEBUG]: - result += "%sout: %s%s\n" % (self.blue, self.nocolor, message) + result += "%sout: %s%s" % (self.blue, self.nocolor, message) elif subtype == JERRY_DEBUGGER_OUTPUT_WARNING: - result += "%swarning: %s%s\n" % (self.yellow, self.nocolor, message) + result += "%swarning: %s%s" % (self.yellow, self.nocolor, message) elif subtype == JERRY_DEBUGGER_OUTPUT_ERROR: - result += "%serr: %s%s\n" % (self.red, self.nocolor, message) + result += "%serr: %s%s" % (self.red, self.nocolor, message) elif subtype == JERRY_DEBUGGER_OUTPUT_TRACE: - result += "%strace: %s%s\n" % (self.blue, self.nocolor, message) + result += "%strace: %s%s" % (self.blue, self.nocolor, message) # Subtypes of eval - elif buffer_type == JERRY_DEBUGGER_EVAL_RESULT_END: + else: + self.prompt = True + if subtype == JERRY_DEBUGGER_EVAL_ERROR: result += "Uncaught exception: %s" % (message) else: result += message - self.smessage = result - return DisplayData("eval_result", self.smessage) + + return DebuggerAction(DebuggerAction.TEXT, result) elif buffer_type == JERRY_DEBUGGER_MEMSTATS_RECEIVE: - memory_stats = struct.unpack(self.byte_order + self.idx_format *5, - data[3: 3 + 4 *5]) + memory_stats = struct.unpack(self.byte_order + self.idx_format * 5, + data[3: 3 + 4 * 5]) result += "Allocated bytes: %s\n" % memory_stats[0] result += "Byte code bytes: %s\n" % memory_stats[1] @@ -891,8 +880,8 @@ class JerryDebugger(object): result += "Object bytes: %s\n" % memory_stats[3] result += "Property bytes: %s\n" % memory_stats[4] - self.smessage = str(result) - return DisplayData("memstats", self.smessage) + self.prompt = True + return DebuggerAction(DebuggerAction.TEXT, result) elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE: self.send_client_source() @@ -900,11 +889,11 @@ class JerryDebugger(object): raise Exception("Unknown message") def print_source(self, line_num, offset): - msg = '' + msg = "" last_bp = self.last_breakpoint_hit if not last_bp: - return None + return "" lines = last_bp.function.source if last_bp.function.source_name: @@ -933,20 +922,9 @@ class JerryDebugger(object): self.nocolor, lines[i]) else: msg += "%s%4d%s %s\n" % (self.green, i + 1, self.nocolor, lines[i]) - msg = msg[:-1] - return DisplayData("print_source", msg) - def not_empty(self, args): - if args is not None: - return True + return msg - def wait_data(self, args): - if args is None: - return True - - def check_empty_data(self, args): - if not args: - return True # pylint: disable=too-many-branches,too-many-locals,too-many-statements def _parse_source(debugger, data): @@ -962,7 +940,7 @@ def _parse_source(debugger, data): while True: if data is None: - return + return "Error: connection lost during source code receiving" buffer_type = ord(data[2]) buffer_size = ord(data[1]) - 1 @@ -970,8 +948,8 @@ def _parse_source(debugger, data): logging.debug("Parser buffer type: %d, message size: %d", buffer_type, buffer_size) if buffer_type == JERRY_DEBUGGER_PARSE_ERROR: - logging.error("Parser error!") - return + logging.error("Syntax error found") + return "" elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]: source_code += data[3:] @@ -1054,7 +1032,7 @@ def _parse_source(debugger, data): else: logging.error("Parser error!") - return + raise Exception("Unexpected message") data = debugger.get_message(True) @@ -1067,31 +1045,39 @@ def _parse_source(debugger, data): # Try to set the pending breakpoints if debugger.pending_breakpoint_list: + result = "" logging.debug("Pending breakpoints list: %s", debugger.pending_breakpoint_list) bp_list = debugger.pending_breakpoint_list for breakpoint_index, breakpoint in bp_list.items(): - for src in debugger.function_list.values(): + source_lines = 0 + for src in new_function_list.values(): if src.source_name == breakpoint.source_name: source_lines = len(src.source) - else: - source_lines = 0 + break if breakpoint.line: if breakpoint.line <= source_lines: command = breakpoint.source_name + ":" + str(breakpoint.line) - if _set_breakpoint(debugger, command, True): + set_result = _set_breakpoint(debugger, command, True) + + if set_result: + result += set_result del bp_list[breakpoint_index] elif breakpoint.function: command = breakpoint.function - if _set_breakpoint(debugger, command, True): + set_result = _set_breakpoint(debugger, command, True) + + if set_result: + result += set_result del bp_list[breakpoint_index] if not bp_list: debugger.send_parser_config(0) + return result - else: - logging.debug("No pending breakpoints") + logging.debug("No pending breakpoints") + return "" def _release_function(debugger, data): @@ -1112,30 +1098,31 @@ def _release_function(debugger, data): def _enable_breakpoint(debugger, breakpoint): if isinstance(breakpoint, JerryPendingBreakpoint): - if not debugger.breakpoint_pending_exists(breakpoint): - debugger.next_breakpoint_index += 1 - breakpoint.index = debugger.next_breakpoint_index - debugger.pending_breakpoint_list[debugger.next_breakpoint_index] = breakpoint - print("%sPending breakpoint%s at %s" % (debugger.yellow, debugger.nocolor, breakpoint)) - else: - print("%sPending breakpoint%s already exists" % (debugger.yellow, debugger.nocolor)) - else: - if breakpoint.active_index < 0: - debugger.next_breakpoint_index += 1 - debugger.active_breakpoint_list[debugger.next_breakpoint_index] = breakpoint - breakpoint.active_index = debugger.next_breakpoint_index - debugger.send_breakpoint(breakpoint) - if debugger.breakpoint_info: - debugger.breakpoint_info += '\n' - debugger.breakpoint_info += "%sBreakpoint %d %sat %s" % (debugger.green, - breakpoint.active_index, - debugger.nocolor, - breakpoint) + if debugger.breakpoint_pending_exists(breakpoint): + return "%sPending breakpoint%s already exists\n" % (debugger.yellow, debugger.nocolor) + + debugger.next_breakpoint_index += 1 + breakpoint.index = debugger.next_breakpoint_index + debugger.pending_breakpoint_list[debugger.next_breakpoint_index] = breakpoint + return ("%sPending breakpoint %d%s at %s\n" % (debugger.yellow, + breakpoint.index, + debugger.nocolor, + breakpoint)) + if breakpoint.active_index < 0: + debugger.next_breakpoint_index += 1 + debugger.active_breakpoint_list[debugger.next_breakpoint_index] = breakpoint + breakpoint.active_index = debugger.next_breakpoint_index + debugger.send_breakpoint(breakpoint) + + return "%sBreakpoint %d%s at %s\n" % (debugger.green, + breakpoint.active_index, + debugger.nocolor, + breakpoint) def _set_breakpoint(debugger, string, pending): line = re.match("(.*):(\\d+)$", string) - found = False + result = "" if line: source_name = line.group(1) @@ -1147,16 +1134,14 @@ def _set_breakpoint(debugger, string, pending): func_source.endswith("/" + source_name) or func_source.endswith("\\" + source_name)): - _enable_breakpoint(debugger, breakpoint) - found = True + result += _enable_breakpoint(debugger, breakpoint) else: for function in debugger.function_list.values(): if function.name == string: - _enable_breakpoint(debugger, function.lines[function.first_breakpoint_line]) - found = True + result += _enable_breakpoint(debugger, function.lines[function.first_breakpoint_line]) - if not found and not pending: + if not result and not pending: print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \ (debugger.yellow, debugger.nocolor)) @@ -1169,12 +1154,9 @@ def _set_breakpoint(debugger, string, pending): breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1)) else: breakpoint = JerryPendingBreakpoint(function=string) - _enable_breakpoint(debugger, breakpoint) + result += _enable_breakpoint(debugger, breakpoint) - elif not found and pending: - return False - - return True + return result def _get_breakpoint(debugger, breakpoint_data): diff --git a/tests/debugger/do_backtrace.expected b/tests/debugger/do_backtrace.expected index 6cf234c24..21b73f509 100644 --- a/tests/debugger/do_backtrace.expected +++ b/tests/debugger/do_backtrace.expected @@ -15,15 +15,15 @@ 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) (jerry-debugger) bt 1 2 t +Total number of frames: 3 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 Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1) (jerry-debugger) bt 0 3 t +Total number of frames: 3 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 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) @@ -32,9 +32,9 @@ Frame 2: tests/debugger/do_backtrace.js:40 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) (jerry-debugger) bt 2 t +Total number of frames: 3 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 out: function foo Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1) diff --git a/tests/debugger/do_break.expected b/tests/debugger/do_break.expected index 6e5560ee3..07217421e 100644 --- a/tests/debugger/do_break.expected +++ b/tests/debugger/do_break.expected @@ -18,6 +18,7 @@ out: break test out: var cat Stopped at breakpoint:1 tests/debugger/do_break.js:51 (jerry-debugger) delete 1 +Breakpoint 1 deleted (jerry-debugger) list === Active breakpoints === 2: tests/debugger/do_break.js:36 (in test() at line:20, col:1) diff --git a/tests/debugger/do_delete.expected b/tests/debugger/do_delete.expected index bfa158e1b..0a3b714aa 100644 --- a/tests/debugger/do_delete.expected +++ b/tests/debugger/do_delete.expected @@ -7,7 +7,7 @@ Stopped at tests/debugger/do_delete.js:17 Breakpoint 1 at tests/debugger/do_delete.js:17 (jerry-debugger) b do_delete.js:21 No breakpoint found, do you want to add a pending breakpoint? (y or [n]) -Pending breakpoint at do_delete.js:21 +Pending breakpoint 2 at do_delete.js:21 (jerry-debugger) b do_delete.js:19 Breakpoint 3 at tests/debugger/do_delete.js:19 (jerry-debugger) b do_delete.js:18 @@ -20,7 +20,9 @@ Breakpoint 4 at tests/debugger/do_delete.js:18 === Pending breakpoints === 2: do_delete.js:21 (pending) (jerry-debugger) delete 2 +Pending breakpoint 2 deleted (jerry-debugger) delete 3 +Breakpoint 3 deleted (jerry-debugger) list === Active breakpoints === 1: tests/debugger/do_delete.js:17 diff --git a/tests/debugger/do_delete_all.expected b/tests/debugger/do_delete_all.expected index 3d80eb74f..94bb8b122 100644 --- a/tests/debugger/do_delete_all.expected +++ b/tests/debugger/do_delete_all.expected @@ -8,10 +8,10 @@ Breakpoint 2 at tests/debugger/do_delete_all.js:18 Breakpoint 3 at tests/debugger/do_delete_all.js:21 (in delete_test() at line:20, col:1) (jerry-debugger) b do_delete_all:350 No breakpoint found, do you want to add a pending breakpoint? (y or [n]) -Pending breakpoint at do_delete_all:350 +Pending breakpoint 4 at do_delete_all:350 (jerry-debugger) b do_delete_all:37 No breakpoint found, do you want to add a pending breakpoint? (y or [n]) -Pending breakpoint at do_delete_all:37 +Pending breakpoint 5 at do_delete_all:37 (jerry-debugger) list === Active breakpoints === 1: tests/debugger/do_delete_all.js:17 diff --git a/tests/debugger/do_pending_breakpoints.expected b/tests/debugger/do_pending_breakpoints.expected index 33efcc263..df6260fc7 100644 --- a/tests/debugger/do_pending_breakpoints.expected +++ b/tests/debugger/do_pending_breakpoints.expected @@ -2,10 +2,10 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_pending_breakpoints.js:15 (jerry-debugger) break :1 No breakpoint found, do you want to add a pending breakpoint? (y or [n]) -Pending breakpoint at :1 +Pending breakpoint 1 at :1 (jerry-debugger) break f No breakpoint found, do you want to add a pending breakpoint? (y or [n]) -Pending breakpoint at f() +Pending breakpoint 2 at f() (jerry-debugger) list === Pending breakpoints === 1: :1 (pending)