[pypy-commit] pypy reverse-debugger: in-progress

arigo pypy.commits at gmail.com
Tue Aug 9 12:05:55 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r86118:9a959ce7e35a
Date: 2016-08-09 18:05 +0200
http://bitbucket.org/pypy/pypy/changeset/9a959ce7e35a/

Log:	in-progress

diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -284,7 +284,6 @@
                requires=[('translation.split_gc_address_space', True),
                          ('translation.jit', False),
                          ('translation.gc', 'boehm'),
-                         ('translation.thread', False),
                          ('translation.continuation', False)]),
 ])
 
diff --git a/rpython/translator/c/src/thread.h b/rpython/translator/c/src/thread.h
--- a/rpython/translator/c/src/thread.h
+++ b/rpython/translator/c/src/thread.h
@@ -26,6 +26,10 @@
 
 #endif /* !_WIN32 */
 
+#ifdef RPY_REVERSE_DEBUGGER
+RPY_EXTERN void rpy_reverse_db_thread_switch(void);
+#endif
+
 RPY_EXTERN void RPyGilAllocate(void);
 RPY_EXTERN long RPyGilYieldThread(void);
 RPY_EXTERN void RPyGilAcquireSlowPath(long);
@@ -45,6 +49,9 @@
     long old_fastgil = pypy_lock_test_and_set(&rpy_fastgil, 1);
     if (old_fastgil != 0)
         RPyGilAcquireSlowPath(old_fastgil);
+#ifdef RPY_REVERSE_DEBUGGER
+    rpy_reverse_db_thread_switch();
+#endif
 }
 static inline void _RPyGilRelease(void) {
     assert(RPY_FASTGIL_LOCKED(rpy_fastgil));
diff --git a/rpython/translator/revdb/gencsupp.py b/rpython/translator/revdb/gencsupp.py
--- a/rpython/translator/revdb/gencsupp.py
+++ b/rpython/translator/revdb/gencsupp.py
@@ -82,9 +82,10 @@
                '_revdb_do_all_calls_', False):
         return call_code   # a hack for ll_call_destructor() to mean
                            # that the calls should really be done
-    # haaaaack
+    #
+    # hack: we don't need the flag for at least these two common functions
     if call_code in ('RPyGilRelease();', 'RPyGilAcquire();'):
-        return '/* ' + call_code + ' */'
+        return 'RPY_REVDB_CALL_GILCTRL(%s);' % (call_code,)
     #
     tp = funcgen.lltypename(v_result)
     if tp == 'void @':
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
@@ -35,6 +35,7 @@
 #define WEAKREF_AFTERWARDS_ALIVE   ((char)0xeb)
 
 #define ASYNC_FINALIZER_TRIGGER    ((int16_t)0xff46)
+#define ASYNC_THREAD_SWITCH        ((int16_t)0xff54)
 
 #define FID_REGULAR_MODE           'R'
 #define FID_SAVED_STATE            'S'
@@ -55,6 +56,8 @@
 static char rpy_rev_buffer[16384];    /* max. 32768 */
 int rpy_rev_fileno = -1;
 static char flag_io_disabled = FID_REGULAR_MODE;
+static pthread_t current_logged_thread;
+static bool_t current_logged_thread_seen;
 
 
 static void setup_record_mode(int argc, char *argv[]);
@@ -321,6 +324,21 @@
 
 static long in_invoke_finalizers;
 
+static void emit_async_block(int async_code, uint64_t content)
+{
+    char *p = rpy_rev_buffer;
+
+    _RPY_REVDB_LOCK();
+    rpy_reverse_db_flush();
+    assert(current_packet_size() == 0);
+
+    *(int16_t *)p = async_code;
+    memcpy(rpy_revdb.buf_p, &content, sizeof(uint64_t));
+    rpy_revdb.buf_p += sizeof(uint64_t);
+    flush_buffer();
+    _RPY_REVDB_UNLOCK();
+}
+
 static void record_stop_point(void)
 {
     /* ===== FINALIZERS =====
@@ -332,19 +350,10 @@
        conceptually just *after* the stop point.
      */
     int i;
-    char *p = rpy_rev_buffer;
     int64_t done;
 
     /* Write an ASYNC_FINALIZER_TRIGGER packet */
-    _RPY_REVDB_LOCK();
-    rpy_reverse_db_flush();
-    assert(current_packet_size() == 0);
-
-    *(int16_t *)p = ASYNC_FINALIZER_TRIGGER;
-    memcpy(rpy_revdb.buf_p, &rpy_revdb.stop_point_seen, sizeof(uint64_t));
-    rpy_revdb.buf_p += sizeof(uint64_t);
-    flush_buffer();
-    _RPY_REVDB_UNLOCK();
+    emit_async_block(ASYNC_FINALIZER_TRIGGER, rpy_revdb.stop_point_seen);
 
     /* Invoke all Boehm finalizers.  For new-style finalizers, this
        will only cause them to move to the queues, where
@@ -365,6 +374,26 @@
 }
 
 RPY_EXTERN
+void rpy_reverse_db_thread_switch(void)
+{
+    /* called at the end of _RPyGilAcquire(), when there was
+       potentially a thread switch.  If there actually was, emit an
+       ASYNC_THREAD_SWITCH block. */
+    pthread_t tself;
+    assert(!RPY_RDB_REPLAY);
+
+    tself = pthread_self();
+    if (!current_logged_thread_seen) {
+        current_logged_thread = tself;
+        current_logged_thread_seen = 1;
+    }
+    else if (!pthread_equal(tself, current_logged_thread)) {
+        emit_async_block(ASYNC_THREAD_SWITCH, (uint64_t)tself);
+        current_logged_thread = tself;
+    }
+}
+
+RPY_EXTERN
 void rpy_reverse_db_call_destructor(void *obj)
 {
     /* old-style finalizers.  Should occur only from the 
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
@@ -137,6 +137,11 @@
             rpy_reverse_db_invoke_callback(_re);                        \
     }
 
+#define RPY_REVDB_CALL_GILCTRL(call_code)                               \
+    if (!RPY_RDB_REPLAY) {                                              \
+        call_code                                                       \
+    }
+
 #define RPY_REVDB_CALLBACKLOC(locnum)                                   \
     rpy_reverse_db_callback_loc(locnum)
 
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
@@ -86,13 +86,13 @@
         return self.cur == len(self.buffer)
 
     def write_call(self, expected_string):
-        x = self.next()   # raw_malloc: the pointer we got
-        self.same_thread()
+        x = self.next()     # raw_malloc: the pointer we got
+        self.same_stack()   # write
         x = self.next(); assert x == len(expected_string)
-        self.same_thread()
+        self.same_stack()   # errno
         x = self.next('i'); assert x == 0      # errno
 
-    def same_thread(self):
+    def same_stack(self):
         x = self.next('c'); assert x == '\xFC'
 
 
diff --git a/rpython/translator/revdb/test/test_callback.py b/rpython/translator/revdb/test/test_callback.py
--- a/rpython/translator/revdb/test/test_callback.py
+++ b/rpython/translator/revdb/test/test_callback.py
@@ -63,14 +63,14 @@
         self.compile(main, backendopt=False)
         out = self.run('Xx')
         rdb = self.fetch_rdb([self.exename, 'Xx'])
-        rdb.same_thread()                       # callmesimple()
+        rdb.same_stack()                        # callmesimple()
         x = rdb.next('i'); assert x == 55555
         rdb.write_call('55555\n')
         b = rdb.next('!h'); assert 300 <= b < 310  # -> callback
         x = rdb.next('i'); assert x == 40       # arg n
         x = rdb.next('!h'); assert x == b       # -> callback
         x = rdb.next('i'); assert x == 3        # arg n
-        rdb.same_thread()                       # <- return in main thread
+        rdb.same_stack()                        # <- return in main thread
         x = rdb.next('i'); assert x == 4000 * 300   # return from callme()
         rdb.write_call('%s\n' % (4000 * 300,))
         x = rdb.next('q'); assert x == 0      # number of stop points
@@ -87,7 +87,7 @@
         x = rdb.next('!h'); assert x == b       # -> callback again
         x = rdb.next('i'); assert x == 3        # arg n
         rdb.write_call('3\n')
-        rdb.same_thread()                       # -> return in main thread
+        rdb.same_stack()                        # -> return in main thread
         x = rdb.next('i'); assert x == 120      # <- return from callme()
         rdb.write_call('120\n')
         x = rdb.next('q'); assert x == 2        # number of stop points
diff --git a/rpython/translator/revdb/test/test_weak.py b/rpython/translator/revdb/test/test_weak.py
--- a/rpython/translator/revdb/test/test_weak.py
+++ b/rpython/translator/revdb/test/test_weak.py
@@ -203,7 +203,7 @@
                 assert time == i + 1
                 y = intmask(rdb.next('q')); assert y == -1
                 triggered = True
-            rdb.same_thread()
+            rdb.same_stack()
             j = rdb.next()
             assert j == i + 1000000 * triggered
             if triggered:
@@ -215,7 +215,7 @@
                     assert uid > 0 and uid not in uid_seen
                     uid_seen.add(uid)
                     lst.append(uid)
-                rdb.same_thread()
+                rdb.same_stack()
                 totals.append((lst, intmask(rdb.next())))
         x = rdb.next('q'); assert x == 3000    # number of stop points
         #
@@ -245,13 +245,13 @@
                     assert x != -1
                     assert x not in seen_uids
                     seen_uids.add(x)
-                    rdb.same_thread()
+                    rdb.same_stack()
                     y = intmask(rdb.next())
                     assert y == -7      # from the __del__
                     x = intmask(rdb.next())
                     if x == -1:
                         break
-            rdb.same_thread()
+            rdb.same_stack()
             x = rdb.next()
             assert x == len(seen_uids)
         assert len(seen_uids) == int(out)


More information about the pypy-commit mailing list