Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r86788:8aa212be6c45
Date: 2016-08-31 19:07 +0100
http://bitbucket.org/pypy/pypy/changeset/8aa212be6c45/
Log: user interface
diff --git a/pypy/interpreter/reverse_debugging.py
b/pypy/interpreter/reverse_debugging.py
--- a/pypy/interpreter/reverse_debugging.py
+++ b/pypy/interpreter/reverse_debugging.py
@@ -605,6 +605,7 @@
# if it is empty, complain
if not name:
revdb.send_output("Empty breakpoint name\n")
+ revdb.send_change_breakpoint(i)
return
# if it is surrounded by < >, it is the name of a code object
if name.startswith('<') and name.endswith('>'):
@@ -621,7 +622,7 @@
if not valid_identifier(name):
revdb.send_output(
'Note: "%s()" doesn''t look like a function name. '
- 'Setting breakpoint anyway\n' % (name,))
+ 'Setting breakpoint anyway\n' % name)
add_breakpoint_funcname(name, i)
return
# "number" does the same as ":number"
@@ -633,6 +634,7 @@
except ValueError:
revdb.send_output('"%s": expected a line number after colon\n' % (
name,))
+ revdb.send_change_breakpoint(i)
return
filename = name[:j]
@@ -642,6 +644,7 @@
if filename == '':
frame = fetch_cur_frame()
if frame is None:
+ revdb.send_change_breakpoint(i)
return
filename = frame.getcode().co_filename
elif filename.startswith('<') and filename.endswith('>'):
@@ -649,7 +652,7 @@
elif not filename.lower().endswith('.py'):
# use unmodified, but warn
revdb.send_output(
- 'Note: "%s" doesn''t look like a co_filename. '
+ 'Note: "%s" doesn''t look like a Python filename. '
'Setting breakpoint anyway\n' % (filename,))
elif '\x00' not in filename:
filename = rstring.assert_str0(filename)
diff --git a/pypy/interpreter/test/test_reverse_debugging.py
b/pypy/interpreter/test/test_reverse_debugging.py
--- a/pypy/interpreter/test/test_reverse_debugging.py
+++ b/pypy/interpreter/test/test_reverse_debugging.py
@@ -77,13 +77,14 @@
got_output = None
got_chbkpt = None
- if messages:
- assert len(messages) <= 1
- if messages[0][0] == revdb.ANSWER_TEXT:
- got_output = messages[0][-1]
- if messages[0][0] == revdb.ANSWER_CHBKPT:
- assert messages[0][1] == 5
- got_chbkpt = messages[0][-1]
+ for msg in messages:
+ if msg[0] == revdb.ANSWER_TEXT:
+ assert got_output is None
+ got_output = msg[-1]
+ elif msg[0] == revdb.ANSWER_CHBKPT:
+ assert got_chbkpt is None
+ assert msg[1] == 5
+ got_chbkpt = msg[-1]
assert got_output == expected_output
assert got_chbkpt == expected_chbkpt
@@ -92,7 +93,8 @@
return rpath.rnormpath(rpath.rabspath(path))
def test_add_breakpoint():
- check_add_breakpoint('', expected_output="Empty breakpoint name\n")
+ check_add_breakpoint('', expected_output="Empty breakpoint name\n",
+ expected_chbkpt='')
check_add_breakpoint('foo42', expected_funcname="foo42")
check_add_breakpoint('foo.bar', expected_funcname="foo.bar",
expected_output='Note: "foo.bar()" doesn''t look like a function name.'
@@ -105,7 +107,7 @@
expected_fileline=('abcd', 42),
expected_chbkpt='abcd:42')
check_add_breakpoint('abcd:42', expected_fileline=('abcd', 42),
- expected_output='Note: "abcd" doesnt look like a co_filename.'
+ expected_output='Note: "abcd" doesnt look like a Python filename.'
' Setting breakpoint anyway\n')
full = fullpath('abcd.py')
check_add_breakpoint('abcd.py:42',
@@ -113,3 +115,6 @@
expected_chbkpt='%s:42' % full)
check_add_breakpoint('%s:42' % full,
expected_fileline=(full, 42))
+ check_add_breakpoint('42:abc',
+ expected_output='"42:abc": expected a line number after colon\n',
+ expected_chbkpt='')
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -55,7 +55,7 @@
def send_linecache(filename, linenum, strip=True):
send_answer(ANSWER_LINECACHE, linenum, int(strip), extra=filename)
-def send_change_breakpoint(breakpointnum, newtext):
+def send_change_breakpoint(breakpointnum, newtext=''):
send_answer(ANSWER_CHBKPT, breakpointnum, extra=newtext)
def current_time():
diff --git a/rpython/translator/revdb/interact.py
b/rpython/translator/revdb/interact.py
--- a/rpython/translator/revdb/interact.py
+++ b/rpython/translator/revdb/interact.py
@@ -184,20 +184,13 @@
new = 1
while new in b.num2break:
new += 1
- if len(break_at) > 0xFFFFFF:
- raise OverflowError("break/watchpoint too complex")
- b.num2break[new] = (break_code +
- chr(len(break_at) & 0xFF) +
- chr((len(break_at) >> 8) & 0xFF) +
- chr(len(break_at) >> 16) +
- break_at)
+ b.set_num2break(new, break_code, break_at)
b.sources[new] = source_expr
if break_code == 'W':
b.watchvalues[new] = ''
if nids:
b.watchuids[new] = self.pgroup.nids_to_uids(nids)
- kind, name = self._bp_kind(new)
- print "%s %d added" % (kind.capitalize(), new)
+ return new
def cmd_info_breakpoints(self):
"""List current breakpoints and watchpoints"""
@@ -422,7 +415,18 @@
if not argument:
print "Break where?"
return
- self._bp_new(argument, 'B', argument)
+ num = self._bp_new(argument, 'B', argument)
+ b = self.pgroup.edit_breakpoints()
+ old = b.num2break[num]
+ self.pgroup.update_breakpoints()
+ new = b.num2break.get(num)
+ if old == new:
+ print "Breakpoint %d added" % (num,)
+ elif new is None:
+ print "Breakpoint not added"
+ else:
+ kind, name = self._bp_kind(num)
+ print "Breakpoint %d added as: %s" % (num, name)
command_b = command_break
def command_delete(self, argument):
@@ -458,8 +462,9 @@
print 'Watchpoint not added'
return
#
- self._bp_new(argument, 'W', compiled_code, nids=nids)
+ new = self._bp_new(argument, 'W', compiled_code, nids=nids)
self.pgroup.update_watch_values()
+ print "Watchpoint %d added" % (new,)
def getlinecacheoutput(self, pygments_background):
if not pygments_background or pygments_background == 'off':
diff --git a/rpython/translator/revdb/message.py
b/rpython/translator/revdb/message.py
--- a/rpython/translator/revdb/message.py
+++ b/rpython/translator/revdb/message.py
@@ -78,6 +78,10 @@
# Message(ANSWER_WATCH, ok_flag, extra=result_of_expr)
ANSWER_WATCH = 23
+# sent sometimes after CMD_BREAKPOINTS:
+# Message(ANSWER_CHBKPT, bkpt_num, extra=new_breakpoint_text)
+ANSWER_CHBKPT = 24
+
# ____________________________________________________________
diff --git a/rpython/translator/revdb/process.py
b/rpython/translator/revdb/process.py
--- a/rpython/translator/revdb/process.py
+++ b/rpython/translator/revdb/process.py
@@ -60,6 +60,15 @@
a.thread_num = self.thread_num
return a
+ def set_num2break(self, new, break_code, break_at):
+ if len(break_at) > 0xFFFFFF:
+ raise OverflowError("break/watchpoint too complex")
+ self.num2break[new] = (break_code +
+ chr(len(break_at) & 0xFF) +
+ chr((len(break_at) >> 8) & 0xFF) +
+ chr(len(break_at) >> 16) +
+ break_at)
+
class RecreateSubprocess(Exception):
pass
@@ -218,6 +227,16 @@
sys.stdout.flush()
elif msg.cmd == ANSWER_ATTEMPT_IO:
raise RecreateSubprocess
+ elif msg.cmd == ANSWER_CHBKPT and pgroup is not None:
+ # change the breakpoint definition. Needed for
+ # ":linenum" breakpoints which must be expanded to the
+ # current file only once
+ b = pgroup.edit_breakpoints()
+ assert b.num2break[msg.arg1][0] == 'B'
+ if msg.extra:
+ b.set_num2break(msg.arg1, 'B', msg.extra)
+ else:
+ del b.set_num2break[msg.arg1]
else:
print >> sys.stderr, "unexpected %r" % (msg,)
@@ -399,7 +418,7 @@
arg2 = self.all_breakpoints.thread_num
extra = ''.join(flat)
self.active.send(Message(CMD_BREAKPOINTS, arg1, arg2, extra=extra))
- self.active.expect_ready()
+ self.active.print_text_answer(pgroup=self)
else:
assert cmp == 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit