Skip to content

Commit a459511

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 5f4a220 commit a459511

File tree

3 files changed

+811
-663
lines changed

3 files changed

+811
-663
lines changed

jerry-debugger/jerry_client.py

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

0 commit comments

Comments
 (0)