Skip to content

Commit 36874be

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 acdbbf2 commit 36874be

File tree

3 files changed

+779
-636
lines changed

3 files changed

+779
-636
lines changed

jerry-debugger/jerry_client.py

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
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 cmd import Cmd
18+
from pprint import pprint
19+
import math
20+
import socket
21+
import sys
22+
import logging
23+
import time
24+
import jerry_client_ws
25+
26+
class DebuggerPrompt(Cmd):
27+
28+
def __init__(self, debugger):
29+
Cmd.__init__(self)
30+
self.debugger = debugger
31+
self.stop = False
32+
self.quit = False
33+
self.cont = True
34+
self.debugger.non_interactive = False
35+
self.dsp = 0
36+
self.display = 0
37+
self.show = 0
38+
39+
def precmd(self, line):
40+
self.stop = False
41+
self.cont = False
42+
if self.debugger.non_interactive:
43+
print("%s" % line)
44+
return line
45+
46+
def postcmd(self, stop, line):
47+
return self.stop
48+
49+
def do_quit(self, _):
50+
""" Exit JerryScript debugger """
51+
self.debugger.quit()
52+
self.cont = False
53+
self.quit = True
54+
self.stop = True
55+
56+
def do_display(self, args):
57+
""" Toggle source code display after breakpoints """
58+
self.cont = False
59+
if args:
60+
line_num = src_check_args(args)
61+
if line_num >= 0:
62+
self.display = line_num
63+
else:
64+
return
65+
else:
66+
print("Non-negative integer number expected, 0 turns off this function")
67+
return
68+
if self.dsp > 0 and self.display == 0:
69+
self.debugger.stop()
70+
71+
def do_break(self, args):
72+
""" Insert breakpoints on the given lines or functions """
73+
if args == "":
74+
print("Error: Breakpoint index expected")
75+
elif ':' in args:
76+
try:
77+
args_second = int(args.split(':', 1)[1])
78+
if args_second < 0:
79+
print("Error: Positive breakpoint index expected")
80+
else:
81+
sbreak = self.debugger.set_break(args)
82+
except ValueError as val_errno:
83+
print("Error: Positive breakpoint index expected: %s" % val_errno)
84+
else:
85+
sbreak = self.debugger.set_break(args)
86+
if sbreak is not None:
87+
print(sbreak)
88+
do_b = do_break
89+
90+
def do_list(self, _):
91+
""" Lists the available breakpoints """
92+
if self.debugger.active_breakpoint_list:
93+
print("=== %sActive breakpoints %s ===" % (self.debugger.green_bg, self.debugger.nocolor))
94+
for breakpoint in self.debugger.active_breakpoint_list.values():
95+
print(" %d: %s" % (breakpoint.active_index, breakpoint))
96+
97+
if self.debugger.pending_breakpoint_list:
98+
print("=== %sPending breakpoints%s ===" % (self.debugger.yellow_bg, self.debugger.nocolor))
99+
for breakpoint in self.debugger.pending_breakpoint_list.values():
100+
print(" %d: %s (pending)" % (breakpoint.index, breakpoint))
101+
102+
if not self.debugger.active_breakpoint_list and not self.debugger.pending_breakpoint_list:
103+
print("No breakpoints")
104+
105+
def do_delete(self, args):
106+
""" Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints """
107+
if not args:
108+
print("Error: Breakpoint index expected")
109+
print("Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints ")
110+
elif args in ['all', 'pending', 'active']:
111+
result = self.debugger.delete(args)
112+
if result != '':
113+
print(result)
114+
else:
115+
try:
116+
result = self.debugger.delete(args)
117+
except ValueError as val_errno:
118+
result = "Error: Integer number expected, %s" % (val_errno)
119+
120+
def do_next(self, args):
121+
""" Next breakpoint in the same context """
122+
self.cont = True
123+
self.stop = True
124+
if not args:
125+
args = 0
126+
self.debugger.next()
127+
else:
128+
try:
129+
args = int(args)
130+
if args <= 0:
131+
raise ValueError(args)
132+
else:
133+
while int(args) != 0:
134+
self.debugger.next()
135+
time.sleep(0.25)
136+
result = self.debugger.mainloop()
137+
if result[-1:] == '\n':
138+
result = result[:-1]
139+
if result != '':
140+
print result
141+
self.debugger.smessage = ''
142+
if self.display > 0:
143+
print self.debugger.print_source(self.debugger, self.display, self.debugger.src_offset)
144+
args = int(args) - 1
145+
self.cmdloop()
146+
except ValueError as val_errno:
147+
print "Error: expected a positive integer: %s" % val_errno
148+
self.cmdloop()
149+
do_n = do_next
150+
151+
def do_step(self, _):
152+
""" Next breakpoint, step into functions """
153+
self.debugger.step()
154+
self.cont = True
155+
self.stop = True
156+
do_s = do_step
157+
158+
def do_backtrace(self, args):
159+
""" Get backtrace data from debugger """
160+
self.debugger.backtrace(args)
161+
self.show = 1
162+
self.stop = True
163+
do_bt = do_backtrace
164+
165+
def do_src(self, args):
166+
""" Get current source code """
167+
if args:
168+
line_num = src_check_args(args)
169+
if line_num >= 0:
170+
print(self.debugger.print_source(line_num, 0))
171+
elif line_num == 0:
172+
print(self.debugger.print_source(self.debugger.default_viewrange, 0))
173+
else:
174+
return
175+
do_source = do_src
176+
177+
def do_scroll(self, _):
178+
""" Scroll the source up or down """
179+
while True:
180+
key = sys.stdin.readline()
181+
if key == 'w\n':
182+
self._scroll_direction("up")
183+
elif key == 's\n':
184+
self._scroll_direction("down")
185+
elif key == 'q\n':
186+
break
187+
else:
188+
print("Invalid key")
189+
190+
def _scroll_direction(self, direction):
191+
""" Helper function for do_scroll """
192+
self.debugger.src_offset_diff = int(max(math.floor(self.debugger.display / 3), 1))
193+
if direction == "up":
194+
self.debugger.src_offset -= self.debugger.src_offset_diff
195+
print(self.debugger.print_source(self.debugger.display, self.debugger.src_offset))
196+
else:
197+
self.debugger.src_offset += self.debugger.src_offset_diff
198+
print(self.debugger.print_source(self.debugger.display, self.debugger.src_offset))
199+
200+
def do_continue(self, _):
201+
""" Continue execution """
202+
self.debugger.get_continue()
203+
self.stop = True
204+
self.cont = True
205+
if not self.debugger.non_interactive:
206+
print("Press enter to stop JavaScript execution.")
207+
do_c = do_continue
208+
209+
def do_finish(self, _):
210+
""" Continue running until the current function returns """
211+
self.debugger.finish()
212+
self.stop = True
213+
do_f = do_finish
214+
215+
def do_dump(self, args):
216+
""" Dump all of the debugger data """
217+
if args:
218+
print("Error: No argument expected")
219+
else:
220+
pprint(self.debugger.function_list)
221+
222+
def do_eval(self, args):
223+
""" Evaluate JavaScript source code """
224+
self.debugger.eval(args)
225+
self.stop = True
226+
self.cont = True
227+
do_e = do_eval
228+
229+
def do_memstats(self, _):
230+
""" Memory statistics """
231+
self.debugger.memstats()
232+
self.stop = True
233+
self.cont = True
234+
do_ms = do_memstats
235+
236+
def do_abort(self, args):
237+
""" Throw an exception """
238+
self.debugger.abort(args)
239+
self.stop = True
240+
self.cont = True
241+
242+
def do_throw(self, args):
243+
""" Throw an exception """
244+
self.debugger.throw(args)
245+
self.stop = True
246+
self.cont = True
247+
248+
def do_exception(self, args):
249+
""" Config the exception handler module """
250+
print(self.debugger.exception(args))
251+
252+
def src_check_args(args):
253+
try:
254+
line_num = int(args)
255+
if line_num < 0:
256+
print("Error: Non-negative integer number expected")
257+
return -1
258+
259+
return line_num
260+
except ValueError as val_errno:
261+
print("Error: Non-negative integer number expected: %s" % (val_errno))
262+
return -1
263+
264+
265+
def main():
266+
args = jerry_client_ws.arguments_parse()
267+
268+
debugger = jerry_client_ws.JerryDebugger(args.address)
269+
270+
non_interactive = args.non_interactive
271+
272+
logging.debug("Connected to JerryScript on %d port", debugger.port)
273+
274+
prompt = DebuggerPrompt(debugger)
275+
prompt.prompt = "(jerry-debugger) "
276+
prompt.debugger.non_interactive = non_interactive
277+
278+
if args.color:
279+
debugger.set_colors()
280+
281+
if args.display:
282+
prompt.dsp = 1
283+
debugger.display = args.display
284+
prompt.do_display(args.display)
285+
prompt.cont = False
286+
else:
287+
prompt.dsp = 0
288+
prompt.stop = False
289+
prompt.cont = False
290+
if not args.client_source:
291+
prompt.debugger.mainloop()
292+
result = prompt.debugger.smessage
293+
print(result)
294+
prompt.debugger.smessage = ''
295+
prompt.cmdloop()
296+
297+
if args.exception is not None:
298+
prompt.do_exception(str(args.exception))
299+
300+
if args.client_source is not None:
301+
if args.client_source != []:
302+
prompt.debugger.store_client_sources(args.client_source)
303+
304+
while True:
305+
if prompt.quit:
306+
break
307+
308+
result = prompt.debugger.mainloop()
309+
310+
if result == '':
311+
break
312+
313+
if result is None:
314+
continue
315+
elif jerry_client_ws.JERRY_DEBUGGER_DATA_END in result:
316+
result = result.replace(jerry_client_ws.JERRY_DEBUGGER_DATA_END, '')
317+
if result[-1:] == '\n':
318+
result = result[:-1]
319+
if result != '':
320+
print(result)
321+
prompt.debugger.smessage = ''
322+
if prompt.display > 0:
323+
print(prompt.debugger.print_source(prompt.display, prompt.debugger.src_offset))
324+
break
325+
else:
326+
if result[-1:] == '\n':
327+
result = result[:-1]
328+
if result != '':
329+
print(result)
330+
prompt.debugger.smessage = ''
331+
if prompt.display > 0:
332+
if prompt.show == 0:
333+
print(prompt.debugger.print_source(prompt.display, prompt.debugger.src_offset))
334+
else:
335+
prompt.show = 0
336+
prompt.cmdloop()
337+
continue
338+
339+
340+
if __name__ == "__main__":
341+
try:
342+
main()
343+
except socket.error as error_msg:
344+
ERRNO = error_msg.errno
345+
MSG = str(error_msg)
346+
if ERRNO == 111:
347+
sys.exit("Failed to connect to the JerryScript debugger.")
348+
elif ERRNO == 32 or ERRNO == 104:
349+
sys.exit("Connection closed.")
350+
else:
351+
sys.exit("Failed to connect to the JerryScript debugger.\nError: %s" % (MSG))

0 commit comments

Comments
 (0)