Skip to content

Commit fdd1c71

Browse files
committed
Splitting the debugger and console part of the python debugger
Move DebuggerPrompt to jerry_client.py Implement JerryDebugger functions in the jerry_client_ws.py file Server response is displayed by jerry_client.py JerryScript-DCO-1.0-Signed-off-by: Tamas Zakor [email protected]
1 parent dfc0757 commit fdd1c71

File tree

3 files changed

+783
-645
lines changed

3 files changed

+783
-645
lines changed

jerry-debugger/jerry_client.py

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright JS Foundation and other contributors, http://js.foundation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from __future__ import print_function
18+
from cmd import Cmd
19+
from pprint import pprint
20+
import math
21+
import socket
22+
import sys
23+
import logging
24+
import time
25+
import jerry_client_ws
26+
27+
class DebuggerPrompt(Cmd):
28+
# pylint: disable=too-many-instance-attributes,too-many-arguments
29+
def __init__(self, debugger):
30+
Cmd.__init__(self)
31+
self.debugger = debugger
32+
self.stop = False
33+
self.quit = False
34+
self.debugger.non_interactive = False
35+
36+
def precmd(self, line):
37+
self.stop = False
38+
if self.debugger.non_interactive:
39+
print("%s" % line)
40+
return line
41+
42+
def postcmd(self, stop, line):
43+
return self.stop
44+
45+
def do_quit(self, _):
46+
""" Exit JerryScript debugger """
47+
self.debugger.quit()
48+
self.quit = True
49+
self.stop = True
50+
51+
def do_display(self, args):
52+
""" Toggle source code display after breakpoints """
53+
if args:
54+
line_num = src_check_args(args)
55+
if line_num >= 0:
56+
self.debugger.display = line_num
57+
else:
58+
print("Non-negative integer number expected, 0 turns off this function")
59+
60+
def do_break(self, args):
61+
""" Insert breakpoints on the given lines or functions """
62+
result = ""
63+
result = self.debugger.set_break(args)
64+
if self.debugger.not_empty(result):
65+
print(result.get_data())
66+
do_b = do_break
67+
68+
def do_list(self, _):
69+
""" Lists the available breakpoints """
70+
result = self.debugger.show_breakpoint_list()
71+
print(result.get_data())
72+
73+
def do_delete(self, args):
74+
""" Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints """
75+
result = self.debugger.delete(args)
76+
if self.debugger.not_empty(result):
77+
print(result.get_data())
78+
79+
def do_next(self, args):
80+
""" Next breakpoint in the same context """
81+
self.stop = True
82+
if self.debugger.check_empty_data(args):
83+
args = 0
84+
self.debugger.next()
85+
else:
86+
try:
87+
args = int(args)
88+
if args <= 0:
89+
raise ValueError(args)
90+
else:
91+
while int(args) != 0:
92+
self.debugger.next()
93+
time.sleep(0.25)
94+
result = self.debugger.mainloop()
95+
if result[-1:] == '\n':
96+
result = result[:-1]
97+
if result:
98+
print(result.get_data())
99+
self.debugger.smessage = ''
100+
if self.debugger.display > 0:
101+
print(self.debugger.print_source(self.debugger.display,
102+
self.debugger.src_offset).get_data())
103+
args = int(args) - 1
104+
self.cmdloop()
105+
except ValueError as val_errno:
106+
print("Error: expected a positive integer: %s" % val_errno)
107+
self.cmdloop()
108+
do_n = do_next
109+
110+
def do_step(self, _):
111+
""" Next breakpoint, step into functions """
112+
self.debugger.step()
113+
self.stop = True
114+
do_s = do_step
115+
116+
def do_backtrace(self, args):
117+
""" Get backtrace data from debugger """
118+
self.debugger.backtrace(args)
119+
self.stop = True
120+
do_bt = do_backtrace
121+
122+
def do_src(self, args):
123+
""" Get current source code """
124+
if args:
125+
line_num = src_check_args(args)
126+
if line_num >= 0:
127+
print(self.debugger.print_source(line_num, 0).get_data())
128+
do_source = do_src
129+
130+
def do_scroll(self, _):
131+
""" Scroll the source up or down """
132+
while True:
133+
key = sys.stdin.readline()
134+
if key == 'w\n':
135+
_scroll_direction(self.debugger, "up")
136+
elif key == 's\n':
137+
_scroll_direction(self.debugger, "down")
138+
elif key == 'q\n':
139+
break
140+
else:
141+
print("Invalid key")
142+
143+
def do_continue(self, _):
144+
""" Continue execution """
145+
self.debugger.get_continue()
146+
self.stop = True
147+
if self.debugger.check_empty_data(self.debugger.non_interactive):
148+
print("Press enter to stop JavaScript execution.")
149+
do_c = do_continue
150+
151+
def do_finish(self, _):
152+
""" Continue running until the current function returns """
153+
self.debugger.finish()
154+
self.stop = True
155+
do_f = do_finish
156+
157+
def do_dump(self, args):
158+
""" Dump all of the debugger data """
159+
if args:
160+
print("Error: No argument expected")
161+
else:
162+
pprint(self.debugger.function_list)
163+
164+
def do_eval(self, args):
165+
""" Evaluate JavaScript source code """
166+
self.debugger.eval(args)
167+
self.stop = True
168+
do_e = do_eval
169+
170+
def do_memstats(self, _):
171+
""" Memory statistics """
172+
self.debugger.memstats()
173+
self.stop = True
174+
do_ms = do_memstats
175+
176+
def do_abort(self, args):
177+
""" Throw an exception """
178+
self.debugger.abort(args)
179+
self.stop = True
180+
181+
def do_restart(self, _):
182+
""" Restart the engine's debug session """
183+
self.debugger.restart()
184+
self.stop = True
185+
do_res = do_restart
186+
187+
def do_throw(self, args):
188+
""" Throw an exception """
189+
self.debugger.throw(args)
190+
self.stop = True
191+
192+
def do_exception(self, args):
193+
""" Config the exception handler module """
194+
result = self.debugger.exception(args)
195+
print(result.get_data())
196+
197+
def _scroll_direction(debugger, direction):
198+
""" Helper function for do_scroll """
199+
debugger.src_offset_diff = int(max(math.floor(debugger.display / 3), 1))
200+
if direction == "up":
201+
debugger.src_offset -= debugger.src_offset_diff
202+
else:
203+
debugger.src_offset += debugger.src_offset_diff
204+
print(debugger.print_source(debugger.display, debugger.src_offset)['value'])
205+
206+
def src_check_args(args):
207+
try:
208+
line_num = int(args)
209+
if line_num < 0:
210+
print("Error: Non-negative integer number expected")
211+
return -1
212+
213+
return line_num
214+
except ValueError as val_errno:
215+
print("Error: Non-negative integer number expected: %s" % (val_errno))
216+
return -1
217+
218+
# pylint: disable=too-many-branches,too-many-locals,too-many-statements
219+
def main():
220+
args = jerry_client_ws.arguments_parse()
221+
222+
debugger = jerry_client_ws.JerryDebugger(args.address)
223+
224+
logging.debug("Connected to JerryScript on %d port", debugger.port)
225+
226+
prompt = DebuggerPrompt(debugger)
227+
prompt.prompt = "(jerry-debugger) "
228+
prompt.debugger.non_interactive = args.non_interactive
229+
230+
if args.color:
231+
debugger.set_colors()
232+
233+
if args.display:
234+
prompt.debugger.display = args.display
235+
prompt.do_display(args.display)
236+
else:
237+
prompt.stop = False
238+
if prompt.debugger.check_empty_data(args.client_source):
239+
prompt.debugger.mainloop()
240+
result = prompt.debugger.smessage
241+
print(result)
242+
prompt.debugger.smessage = ''
243+
prompt.cmdloop()
244+
245+
if prompt.debugger.not_empty(args.exception):
246+
prompt.do_exception(str(args.exception))
247+
248+
if args.client_source:
249+
prompt.debugger.store_client_sources(args.client_source)
250+
251+
while True:
252+
if prompt.quit:
253+
break
254+
255+
result = prompt.debugger.mainloop().get_data()
256+
257+
if prompt.debugger.check_empty_data(result):
258+
break
259+
260+
if prompt.debugger.wait_data(result):
261+
continue
262+
263+
elif jerry_client_ws.JERRY_DEBUGGER_DATA_END in result:
264+
result = result.replace(jerry_client_ws.JERRY_DEBUGGER_DATA_END, '')
265+
if result.endswith('\n'):
266+
result = result.rstrip()
267+
if result:
268+
print(result)
269+
prompt.debugger.smessage = ''
270+
if prompt.debugger.display > 0:
271+
print(prompt.debugger.print_source(prompt.debugger.display, prompt.debugger.src_offset).get_data())
272+
break
273+
else:
274+
if result.endswith('\n'):
275+
result = result.rstrip()
276+
if result:
277+
print(result)
278+
prompt.debugger.smessage = ''
279+
if prompt.debugger.display > 0:
280+
print(prompt.debugger.print_source(prompt.debugger.display, prompt.debugger.src_offset).get_data())
281+
prompt.cmdloop()
282+
continue
283+
284+
if __name__ == "__main__":
285+
try:
286+
main()
287+
except socket.error as error_msg:
288+
ERRNO = error_msg.errno
289+
MSG = str(error_msg)
290+
if ERRNO == 111:
291+
sys.exit("Failed to connect to the JerryScript debugger.")
292+
elif ERRNO == 32 or ERRNO == 104:
293+
sys.exit("Connection closed.")
294+
else:
295+
sys.exit("Failed to connect to the JerryScript debugger.\nError: %s" % (MSG))

0 commit comments

Comments
 (0)