[pypy-commit] pypy reverse-debugger: jump_in_time(exact=False)

arigo pypy.commits at gmail.com
Tue Jun 14 15:40:46 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r85168:e5d6d6128ad7
Date: 2016-06-14 21:41 +0200
http://bitbucket.org/pypy/pypy/changeset/e5d6d6128ad7/

Log:	jump_in_time(exact=False)

diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -53,14 +53,16 @@
     _change_time('f', time_delta, callback, arg_string)
 
 @specialize.arg(1)
-def jump_in_time(target_time, callback, arg_string):
+def jump_in_time(target_time, callback, arg_string, exact=True):
     """For RPython debug commands: the debugger should run the
     'go <target_time>' command.  This will reset the memory and fork again,
     so you can't save any RPython state and read it back.  You can only
     encode the state you want to save into a string.  In the reloaded
-    process, 'callback(arg_string)' is called.
+    process, 'callback(arg_string)' is called.  If 'exact' is False, go to
+    the fork point before target_time but don't go_forward to exactly
+    target_time afterwards.
     """
-    _change_time('g', target_time, callback, arg_string)
+    _change_time('g' if exact else 'b', target_time, callback, arg_string)
 
 def currently_created_objects():
     """For RPython debug commands: returns the current value of
diff --git a/rpython/translator/revdb/src-revdb/revdb.c b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -233,6 +233,7 @@
 
 struct jump_in_time_s {
     uint64_t target_time;
+    char mode;
     void *callback;
     size_t arg_length;
 };
@@ -531,11 +532,12 @@
 }
 
 static void cmd_go(uint64_t target_time, void callback(RPyString *),
-                   RPyString *arg)
+                   RPyString *arg, char mode)
 {
     struct jump_in_time_s header;
 
     header.target_time = target_time;
+    header.mode = mode;
     header.callback = callback;    /* may be NULL */
     /* ^^^ assumes the fn address is the same in the various forks */
     header.arg_length = arg == NULL ? 0 : RPyString_Size(arg);
@@ -556,7 +558,7 @@
 
     if (process_kind == PK_DEBUG_PROCESS) {
         printf("At end.\n");
-        cmd_go(stop_points, NULL, NULL);
+        cmd_go(stop_points, NULL, NULL, 'g');
         abort();   /* unreachable */
     }
 
@@ -641,7 +643,13 @@
             process_kind = PK_DEBUG_PROCESS;
             assert(jump_in_time.target_time >= rpy_revdb.stop_point_seen);
             most_recent_fork = rpy_revdb.stop_point_seen;
-            rpy_revdb.stop_point_break = jump_in_time.target_time;
+            switch (jump_in_time.mode) {
+            case 'b':    /* go non-exact: stay at most_recent_fork */
+                rpy_revdb.stop_point_break = most_recent_fork;
+                break;
+            default:     /* other modes: go exact */
+                rpy_revdb.stop_point_break = jump_in_time.target_time;
+            }
 
             if (jump_in_time.callback == NULL) {
                 assert(jump_in_time.arg_length == 0);
@@ -671,7 +679,7 @@
                 ;     /* normal exit */
             else {
                 fprintf(stderr, "debugging subprocess died\n");
-                cmd_go((uint64_t)-1, NULL, NULL);
+                cmd_go((uint64_t)-1, NULL, NULL, 'q');
                 abort();    /* unreachable */
             }
         }
@@ -736,7 +744,7 @@
 
 static void act_quit(char *p)
 {
-    cmd_go((uint64_t)-1, NULL, NULL);
+    cmd_go((uint64_t)-1, NULL, NULL, 'q');
 }
 
 static void act_go(char *p)
@@ -746,7 +754,7 @@
         printf("usage: go <target_time>\n");
         return;
     }
-    cmd_go(target_time, NULL, NULL);
+    cmd_go(target_time, NULL, NULL, 'g');
 }
 
 static void act_info(char *p)
@@ -844,10 +852,10 @@
         invoke_argument = arg;
         break;
     }
-    case 'g': {      /* go */
-        cmd_go(time >= 1 ? time : 1, callback, arg);
+    case 'g':       /* go */
+    case 'b':       /* go non exact */
+        cmd_go(time >= 1 ? time : 1, callback, arg, mode);
         abort();    /* unreachable */
-    }
     default:
         abort();    /* unreachable */
     }
diff --git a/rpython/translator/revdb/test/test_basic.py b/rpython/translator/revdb/test/test_basic.py
--- a/rpython/translator/revdb/test/test_basic.py
+++ b/rpython/translator/revdb/test/test_basic.py
@@ -334,6 +334,8 @@
                 revdb.go_forward(1, went_fw, "xx")
             if cmdline == 'change-time':
                 revdb.jump_in_time(2, changed_time, "xyzzy")
+            if cmdline == 'change-time-non-exact':
+                revdb.jump_in_time(2, changed_time, "nonx", exact=False)
             if cmdline == 'set-break-after-0':
                 dbstate.break_after = 0
             if cmdline == 'print-id':
@@ -442,6 +444,16 @@
                       'went-fw zz -> 3\r\n'
                       '(3)$ ')
 
+    def test_change_time_non_exact(self):
+        child = self.replay()
+        child.expectx('(3)$ ')
+        child.sendline('r change-time-non-exact')
+        child.expectx('<<<change-time-non-exact>>>\r\n'
+                      'changed-time nonx -> 1\r\n'
+                      'went-fw zz -> 2\r\n'
+                      'went-fw yy -> 3\r\n'
+                      '(3)$ ')
+
     def test_dynamic_breakpoint(self):
         py.test.skip("unsure if that's needed")
         child = self.replay()


More information about the pypy-commit mailing list