Author: Armin Rigo <ar...@tunes.org>
Branch: reverse-debugger
Changeset: r85463:17761780c45d
Date: 2016-06-29 22:30 +0200
http://bitbucket.org/pypy/pypy/changeset/17761780c45d/

Log:    tweak 'next' and 'bnext' to work with opaque stack frame IDs instead
        of the stack depth

diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -14,13 +14,13 @@
 CMD_BACKTRACE   = 2
 CMD_LOCALS      = 3
 CMD_BREAKPOINTS = 4
-CMD_MOREINFO    = 5
+CMD_STACKID     = 5
 CMD_ATTACHID    = 6
 CMD_CHECKWATCH  = 7
 CMD_WATCHVALUES = 8
 ANSWER_LINECACHE= 19
 ANSWER_TEXT     = 20
-ANSWER_MOREINFO = 21
+ANSWER_STACKID  = 21
 ANSWER_NEXTNID  = 22
 ANSWER_WATCH    = 23
 
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
@@ -196,51 +196,61 @@
     command_bs = command_bstep
 
     @contextmanager
-    def _stack_depth_break(self, range_stop):
-        # add temporarily a breakpoint for "stack_depth < range_stop"
+    def _stack_id_break(self, stack_id):
+        # add temporarily a breakpoint that hits when we enter/leave
+        # the frame identified by 'stack_id'
         b = self.pgroup.edit_breakpoints()
-        b.stack_depth = range_stop
+        b.stack_id = stack_id
         try:
             yield
         finally:
-            b.stack_depth = 0
+            b.stack_id = 0
 
     def command_next(self, argument):
         """Run forward for one step, skipping calls"""
-        depth1 = self.pgroup.get_stack_depth()
-        if self.move_forward(1):
-            depth2 = self.pgroup.get_stack_depth()
-            if depth2 > depth1:
-                # If, after running one step, the stack depth is greater
-                # than before, then continue until it is back to what it was.
-                # Can't do it more directly because the "breakpoint" of
-                # stack_depth is only checked for on function enters and
-                # returns (which simplifies and speeds up things for the
-                # RPython code).
-                with self._stack_depth_break(depth1 + 1):
-                    self.command_continue('')
+        depth1 = self.pgroup.get_stack_id()
+        with self._stack_id_break(depth1):
+            if not self.move_forward(1):
+                # we either hit a regular breakpoint, or we hit the
+                # temporary breakpoint
+                return
+            if depth1 == 0:   # we started outside any frame
+                return
+            if self.pgroup.get_stack_id() == depth1:
+                return        # we are still in the same frame
+        #
+        # If, after running one step, the stack id is different than
+        # before but we didn't leave that frame, then we must have
+        # entered a new one.  Continue until we leave that new frame.
+        # Can't do it more directly because the "breakpoint" of
+        # stack_id is only checked for on function enters and returns
+        # (which simplifies and speeds up things for the RPython
+        # code).
+        self.command_finish('')
     command_n = command_next
 
     def command_bnext(self, argument):
         """Run backward for one step, skipping calls"""
-        depth1 = self.pgroup.get_stack_depth()
-        if self.move_backward(1):
-            depth2 = self.pgroup.get_stack_depth()
-            if depth2 > depth1:
-                # If, after running one bstep, the stack depth is greater
-                # than before, then bcontinue until it is back to what it was.
-                with self._stack_depth_break(depth1 + 1):
-                    self.command_bcontinue('')
+        # similar to command_next()
+        depth1 = self.pgroup.get_stack_id()
+        with self._stack_id_break(depth1):
+            if not self.move_backward(1):
+                return
+            if depth1 == 0:
+                return
+            if self.pgroup.get_stack_id() == depth1:
+                return        # we are still in the same frame
+        self.command_bfinish('')
     command_bn = command_bnext
 
     def command_finish(self, argument):
         """Run forward until the current function finishes"""
-        with self._stack_depth_break(self.pgroup.get_stack_depth()):
+        with self._stack_id_break(self.pgroup.get_stack_id()):
             self.command_continue('')
 
     def command_bfinish(self, argument):
         """Run backward until the current function is called"""
-        with self._stack_depth_break(self.pgroup.get_stack_depth()):
+        with self._stack_id_break(self.pgroup.get_stack_id()):
             self.command_bcontinue('')
 
     def command_continue(self, argument):
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
@@ -14,9 +14,9 @@
 CMD_PRINT       = 1    # Message(CMD_PRINT, extra=expression)
 CMD_BACKTRACE   = 2    # Message(CMD_BACKTRACE)
 CMD_LOCALS      = 3    # Message(CMD_LOCALS)
-CMD_BREAKPOINTS = 4    # Message(CMD_BREAKPOINTS, stack_depth,
+CMD_BREAKPOINTS = 4    # Message(CMD_BREAKPOINTS, stack_id,
                        #         extra="\0-separated names")
-CMD_MOREINFO    = 5    # Message(CMD_MOREINFO)
+CMD_STACKID     = 5    # Message(CMD_STACKID, parent-flag)
 CMD_ATTACHID    = 6    # Message(CMD_ATTACHID, small-num, unique-id)
 CMD_CHECKWATCH  = 7    # Message(CMD_CHECKWATCH, extra=expression)
 CMD_WATCHVALUES = 8    # Message(CMD_WATCHVALUES, extra=texts)
@@ -55,9 +55,13 @@
 #    Message(ANSWER_TEXT, extra=text)
 ANSWER_TEXT       = 20
 
-# sent after CMD_MOREINFO:
-#    Message(ANSWER_MOREINFO, stack_depth)
-ANSWER_MOREINFO   = 21
+# CMD_STACKID returns the id of the current or parent frame (depending
+# on the 'parent-flag' passed in), or 0 if not found.  The id can be just
+# the stack depth, or it can be the unique id of the frame object.  When
+# used in CMD_BREAKPOINTS, it means "break if we are entering/leaving that
+# frame".
+#    Message(ANSWER_STACKID, stack-id)
+ANSWER_STACKID    = 21
 
 # sent from CMD_PRINT to record the existence of a recallable object
 #    Message(ANSWER_NEXTNID, unique-id)
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
@@ -19,16 +19,16 @@
         self.num2name = {}     # {small number: break/watchpoint}
         self.watchvalues = {}  # {small number: resulting text}
         self.watchuids = {}    # {small number: [uid...]}
-        self.stack_depth = 0   # breaks if the depth becomes lower than this
+        self.stack_id = 0      # breaks when leaving/entering this frame; 
0=none
 
     def __repr__(self):
         return 'AllBreakpoints(%r, %r, %r, %d)' % (
             self.num2name, self.watchvalues, self.watchuids,
-            self.stack_depth)
+            self.stack_id)
 
     def compare(self, other):
         if (self.num2name == other.num2name and
-            self.stack_depth == other.stack_depth):
+            self.stack_id == other.stack_id):
             if self.watchvalues == other.watchvalues:
                 return 2     # completely equal
             else:
@@ -37,12 +37,12 @@
             return 0     # different
 
     def is_empty(self):
-        return len(self.num2name) == 0 and self.stack_depth == 0
+        return len(self.num2name) == 0 and self.stack_id == 0
 
     def duplicate(self):
         a = AllBreakpoints()
         a.num2name.update(self.num2name)
-        a.stack_depth = self.stack_depth
+        a.stack_id = self.stack_id
         return a
 
 
@@ -364,7 +364,7 @@
         N = (max(num2name) + 1) if num2name else 0
         if cmp == 0:
             flat = [num2name.get(n, '') for n in range(N)]
-            arg1 = self.all_breakpoints.stack_depth
+            arg1 = self.all_breakpoints.stack_id
             extra = '\x00'.join(flat)
             self.active.send(Message(CMD_BREAKPOINTS, arg1, extra=extra))
             self.active.expect_ready()
@@ -536,8 +536,8 @@
     def edit_breakpoints(self):
         return self.all_breakpoints
 
-    def get_stack_depth(self):
-        self.active.send(Message(CMD_MOREINFO))
-        msg = self.active.expect(ANSWER_MOREINFO, Ellipsis)
+    def get_stack_id(self):
+        self.active.send(Message(CMD_STACKID))
+        msg = self.active.expect(ANSWER_STACKID, Ellipsis)
         self.active.expect_ready()
         return msg.arg1
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to