[pypy-commit] pypy reverse-debugger: updates

arigo pypy.commits at gmail.com
Wed Jun 22 14:31:20 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r85336:1a7eac6b97b3
Date: 2016-06-22 18:32 +0200
http://bitbucket.org/pypy/pypy/changeset/1a7eac6b97b3/

Log:	updates

diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -116,11 +116,11 @@
 # ____________________________________________________________
 
 
- at specialize.arg(2)
-def _change_time(mode, time, callback):
-    ll_callback = llhelper(_CALLBACK_NOARG_FNPTR, callback)
-    llop.revdb_change_time(lltype.Void, mode, time, ll_callback)
-_CALLBACK_NOARG_FNPTR = lltype.Ptr(lltype.FuncType([], lltype.Void))
+## @specialize.arg(2)
+## def _change_time(mode, time, callback):
+##     ll_callback = llhelper(_CALLBACK_NOARG_FNPTR, callback)
+##     llop.revdb_change_time(lltype.Void, mode, time, ll_callback)
+## _CALLBACK_NOARG_FNPTR = lltype.Ptr(lltype.FuncType([], lltype.Void))
 _CALLBACK_GCREF_FNPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF],
                                                    lltype.Void))
 _CMDPTR = rffi.CStructPtr('rpy_revdb_command_s',
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -567,7 +567,6 @@
 
     'revdb_stop_point':     LLOp(),
     'revdb_send_answer':    LLOp(),
-    'revdb_change_time':    LLOp(),
     'revdb_breakpoint':     LLOp(),
     'revdb_get_value':      LLOp(sideeffects=False),
     'revdb_get_unique_id':  LLOp(sideeffects=False),
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
@@ -31,6 +31,7 @@
             last_time = self.pgroup.get_current_time()
             if last_time != previous_time:
                 print
+                self.pgroup.update_watch_values()
             if self.print_extra_pending_info:
                 print self.print_extra_pending_info
                 self.print_extra_pending_info = None
@@ -117,16 +118,15 @@
         else:
             return '?????point'
 
-    def _bp_new(self, break_at, watchvalue=None):
+    def _bp_new(self, break_at):
         b = self.pgroup.edit_breakpoints()
         new = 1
         while new in b.num2name:
             new += 1
         b.num2name[new] = break_at
-        if watchvalue is not None:
-            b.watchvalues[new] = watchvalue
+        if break_at.startswith('W'):
+            b.watchvalues[new] = ''
         print "%s %d added" % (self._bp_kind(break_at).capitalize(), new)
-        return new
 
     def cmd_info_breakpoints(self):
         """List current breakpoints and watchpoints"""
@@ -288,5 +288,5 @@
             print text
             print 'Watchpoint not added'
         else:
-            print 'Current value:', text
-            self._bp_new('W' + argument, watchvalue=text)
+            self._bp_new('W' + argument)
+            self.pgroup.update_watch_values()
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
@@ -75,7 +75,7 @@
         return ''.join(pieces)
 
     def send(self, msg):
-        print 'SENT:', self.pid, msg
+        #print 'SENT:', self.pid, msg
         binary = struct.pack("iIqqq", msg.cmd, len(msg.extra),
                              msg.arg1, msg.arg2, msg.arg3)
         self.control_socket.sendall(binary + msg.extra)
@@ -85,7 +85,7 @@
         cmd, size, arg1, arg2, arg3 = struct.unpack("iIqqq", binary)
         extra = self._recv_all(size)
         msg = Message(cmd, arg1, arg2, arg3, extra)
-        print 'RECV:', self.pid, msg
+        #print 'RECV:', self.pid, msg
         return msg
 
     def expect(self, cmd, arg1=0, arg2=0, arg3=0, extra=""):
@@ -133,7 +133,7 @@
         except socket.error:
             pass
 
-    def forward(self, steps, breakpoint_mode, all_breakpoints):
+    def forward(self, steps, breakpoint_mode):
         """Move this subprocess forward in time.
         Returns the Breakpoint or None.
         """
@@ -149,8 +149,6 @@
                 break
             if bkpt is None:
                 bkpt = Breakpoint(msg.arg1, msg.arg3)
-                all_breakpoints.watchvalues = dict.fromkeys(
-                    all_breakpoints.watchvalues)    # set all values to None
         assert msg.cmd == ANSWER_READY
         self.update_times(msg)
         return bkpt
@@ -175,7 +173,7 @@
                     pgroup.all_printed_objects_lst.append(uid)
                 sys.stdout.write('$%d = ' % nid)
             else:
-                print >> sys.stderr, "unexpected message %d" % (msg.cmd,)
+                print >> sys.stderr, "unexpected %r" % (msg,)
 
 
 class ReplayProcessGroup(object):
@@ -268,8 +266,7 @@
                 break
             assert rel_next_clone >= 0
             if rel_next_clone > 0:
-                bkpt = self.active.forward(rel_next_clone, breakpoint_mode,
-                                           self.all_breakpoints)
+                bkpt = self.active.forward(rel_next_clone, breakpoint_mode)
                 if breakpoint_mode == 'r':
                     latest_bkpt = bkpt or latest_bkpt
                 elif bkpt:
@@ -279,8 +276,7 @@
                 self.paused[self.active.current_time].close()
             clone = self.active.clone()
             self.paused[clone.current_time] = clone
-        bkpt = self.active.forward(steps, breakpoint_mode,
-                                   self.all_breakpoints)
+        bkpt = self.active.forward(steps, breakpoint_mode)
         if breakpoint_mode == 'r':
             bkpt = bkpt or latest_bkpt
         if bkpt:
@@ -349,11 +345,6 @@
                 name = num2name.get(n, '')
                 if name.startswith('W'):
                     text = watchvalues[n]
-                    if text is None:
-                        _, text = self.check_watchpoint_expr(name[1:])
-                        print 'updating watchpoint value: %s => %s' % (
-                            name[1:], text)
-                        watchvalues[n] = text
                 flat.append(text)
             extra = '\x00'.join(flat)
             self.active.send(Message(CMD_WATCHVALUES, extra=extra))
@@ -361,6 +352,18 @@
 
         self.active.breakpoints_cache = self.all_breakpoints.duplicate()
 
+    def update_watch_values(self):
+        seen = set()
+        for num, name in self.all_breakpoints.num2name.items():
+            if name.startswith('W'):
+                _, text = self.check_watchpoint_expr(name[1:])
+                if text != self.all_breakpoints.watchvalues[num]:
+                    print 'updating watchpoint value: %s => %s' % (
+                        name[1:], text)
+                    self.all_breakpoints.watchvalues[num] = text
+                seen.add(num)
+        assert set(self.all_breakpoints.watchvalues) == seen
+
     def check_watchpoint_expr(self, expr):
         self.active.send(Message(CMD_CHECKWATCH, extra=expr))
         msg = self.active.expect(ANSWER_WATCH, Ellipsis, extra=Ellipsis)
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
@@ -396,11 +396,18 @@
     }
 }
 
-static void disable_io(rpy_revdb_t *dinfo)
+static rpy_revdb_t disabled_state;
+static void *disabled_exc[2];
+
+static void disable_io(void)
 {
-    *dinfo = rpy_revdb;   /* save the complete struct */
-    dinfo->saved_exc[0] = pypy_g_ExcData.ed_exc_type;
-    dinfo->saved_exc[1] = pypy_g_ExcData.ed_exc_value;
+    if (flag_io_disabled) {
+        fprintf(stderr, "unexpected recursive disable_io()\n");
+        exit(1);
+    }
+    disabled_state = rpy_revdb;   /* save the complete struct */
+    disabled_exc[0] = pypy_g_ExcData.ed_exc_type;
+    disabled_exc[1] = pypy_g_ExcData.ed_exc_value;
     pypy_g_ExcData.ed_exc_type = NULL;
     pypy_g_ExcData.ed_exc_value = NULL;
     rpy_revdb.buf_p = NULL;
@@ -408,9 +415,13 @@
     flag_io_disabled = 1;
 }
 
-static void enable_io(rpy_revdb_t *dinfo)
+static void enable_io(int restore_breaks)
 {
     uint64_t v1, v2;
+    if (!flag_io_disabled) {
+        fprintf(stderr, "unexpected enable_io()\n");
+        exit(1);
+    }
     flag_io_disabled = 0;
 
     if (pypy_g_ExcData.ed_exc_type != NULL) {
@@ -422,22 +433,23 @@
     /* restore the complete struct, with the exception of '*_break' */
     v1 = rpy_revdb.stop_point_break;
     v2 = rpy_revdb.unique_id_break;
-    rpy_revdb = *dinfo;
-    rpy_revdb.stop_point_break = v1;
-    rpy_revdb.unique_id_break = v2;
-    pypy_g_ExcData.ed_exc_type = dinfo->saved_exc[0];
-    pypy_g_ExcData.ed_exc_value = dinfo->saved_exc[1];
+    rpy_revdb = disabled_state;
+    if (!restore_breaks) {
+        rpy_revdb.stop_point_break = v1;
+        rpy_revdb.unique_id_break = v2;
+    }
+    pypy_g_ExcData.ed_exc_type = disabled_exc[0];
+    pypy_g_ExcData.ed_exc_value = disabled_exc[1];
 }
 
 static void execute_rpy_function(rpy_revdb_command_fn func,
                                  rpy_revdb_command_t *cmd,
                                  RPyString *extra)
 {
-    rpy_revdb_t dinfo;
-    disable_io(&dinfo);
+    disable_io();
     if (setjmp(jmp_buf_cancel_execution) == 0)
         func(cmd, extra);
-    enable_io(&dinfo);
+    enable_io(0);
 }
 
 static void check_at_end(uint64_t stop_points)
@@ -585,13 +597,29 @@
     execute_rpy_function(rpy_revdb_commands.rp_funcs[i], cmd, s);
 }
 
+static void save_state(void)
+{
+    stopped_time = rpy_revdb.stop_point_seen;
+    stopped_uid = rpy_revdb.unique_id_seen;
+    rpy_revdb.unique_id_seen = (-1ULL) << 63;
+}
+
+static void restore_state(void)
+{
+    rpy_revdb.stop_point_seen = stopped_time;
+    rpy_revdb.unique_id_seen = stopped_uid;
+    stopped_time = 0;
+    stopped_uid = 0;
+}
+
 RPY_EXTERN
 bool_t rpy_reverse_db_save_state(void)
 {
     if (stopped_time == 0) {
-        stopped_time = rpy_revdb.stop_point_seen;
-        stopped_uid = rpy_revdb.unique_id_seen;
-        rpy_revdb.unique_id_seen = (-1ULL) << 63;
+        save_state();
+        disable_io();
+        rpy_revdb.stop_point_break = 0;
+        rpy_revdb.unique_id_break = 0;
         return 1;
     }
     else
@@ -601,17 +629,15 @@
 RPY_EXTERN
 void rpy_reverse_db_restore_state(void)
 {
-    rpy_revdb.stop_point_seen = stopped_time;
-    rpy_revdb.unique_id_seen = stopped_uid;
-    stopped_time = 0;
-    stopped_uid = 0;
+    enable_io(1);
+    restore_state();
 }
 
 RPY_EXTERN
 void rpy_reverse_db_stop_point(void)
 {
     while (rpy_revdb.stop_point_break == rpy_revdb.stop_point_seen) {
-        rpy_reverse_db_save_state();
+        save_state();
         breakpoint_mode = 0;
 
         if (pending_after_forward) {
@@ -621,6 +647,8 @@
         }
         else {
             rpy_revdb_command_t cmd;
+            if (((int64_t)stopped_uid) < 0)
+                attach_gdb();
             write_answer(ANSWER_READY, stopped_time, stopped_uid, 0);
             read_sock(&cmd, sizeof(cmd));
 
@@ -652,7 +680,7 @@
                 break;
             }
         }
-        rpy_reverse_db_restore_state();
+        restore_state();
     }
 }
 
@@ -677,30 +705,6 @@
 }
 
 RPY_EXTERN
-void rpy_reverse_db_change_time(char mode, long long time,
-                                void callback(void))
-{
-    switch (mode) {
-
-    case 'f':        /* forward */
-        if (time < 0) {
-            fprintf(stderr, "revdb.go_forward(): negative amount of steps\n");
-            exit(1);
-        }
-        if (stopped_time == 0) {
-            fprintf(stderr, "revdb.go_forward(): not from a debug command\n");
-            exit(1);
-        }
-        rpy_revdb.stop_point_break = stopped_time + time;
-        pending_after_forward = callback;
-        break;
-
-    default:
-        abort();    /* unreachable */
-    }
-}
-
-RPY_EXTERN
 void rpy_reverse_db_breakpoint(int64_t num)
 {
     if (stopped_time != 0) {
@@ -750,12 +754,12 @@
         exit(1);
     }
     if (rpy_revdb_commands.rp_alloc) {
-        rpy_revdb_t dinfo;
-        rpy_reverse_db_save_state();
-        disable_io(&dinfo);
+        if (!rpy_reverse_db_save_state()) {
+            fprintf(stderr, "unexpected recursive unique_id_break\n");
+            exit(1);
+        }
         if (setjmp(jmp_buf_cancel_execution) == 0)
             rpy_revdb_commands.rp_alloc(uid, new_object);
-        enable_io(&dinfo);
         rpy_reverse_db_restore_state();
     }
     rpy_revdb.unique_id_break = *future_next_id++;
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -18,7 +18,6 @@
     char *buf_p, *buf_limit;
     uint64_t stop_point_seen, stop_point_break;
     uint64_t unique_id_seen, unique_id_break;
-    void *saved_exc[2];
 } rpy_revdb_t;
 
 RPY_EXTERN rpy_revdb_t rpy_revdb;
@@ -84,9 +83,6 @@
 #define OP_REVDB_SEND_ANSWER(cmd, arg1, arg2, arg3, ll_string, r)       \
     rpy_reverse_db_send_answer(cmd, arg1, arg2, arg3, ll_string)
 
-#define OP_REVDB_CHANGE_TIME(mode, time, callback, r)                   \
-    rpy_reverse_db_change_time(mode, time, callback)
-
 #define OP_REVDB_BREAKPOINT(num, r)                                     \
     rpy_reverse_db_breakpoint(num)
 
@@ -115,8 +111,6 @@
 RPY_EXTERN void rpy_reverse_db_send_answer(int cmd, int64_t arg1, int64_t arg2,
                                            int64_t arg3, RPyString *extra);
 RPY_EXTERN Signed rpy_reverse_db_identityhash(struct pypy_header0 *obj);
-RPY_EXTERN void rpy_reverse_db_change_time(char mode, long long time,
-                                           void callback(void));
 RPY_EXTERN void rpy_reverse_db_breakpoint(int64_t num);
 RPY_EXTERN long long rpy_reverse_db_get_value(char value_id);
 RPY_EXTERN uint64_t rpy_reverse_db_unique_id_break(void *new_object);


More information about the pypy-commit mailing list