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

Reply via email to