Author: Armin Rigo <[email protected]>
Branch: reverse-debugger
Changeset: r86122:738711fb525a
Date: 2016-08-09 22:41 +0200
http://bitbucket.org/pypy/pypy/changeset/738711fb525a/

Log:    recording threads

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
@@ -254,7 +254,7 @@
     rpy_revdb.buf_limit = rpy_rev_buffer + sizeof(rpy_rev_buffer) - 32;
     rpy_revdb.unique_id_seen = 1;
 
-    rpy_active_thread = 1;
+    rpy_active_thread = 0;  /* write an ASYNC_THREAD_SWITCH first in the log */
     rpy_active_thread_ptr = &rpy_active_thread;
 
     pthread_atfork(NULL, NULL, close_revdb_fileno_in_fork_child);
@@ -317,9 +317,10 @@
 
 static void emit_async_block(int async_code, uint64_t content)
 {
+    /* must be called with the lock held */
     char *p = rpy_rev_buffer;
+    assert(rpy_revdb.lock);
 
-    _RPY_REVDB_LOCK();
     rpy_reverse_db_flush();
     assert(current_packet_size() == 0);
 
@@ -327,12 +328,12 @@
     memcpy(rpy_revdb.buf_p, &content, sizeof(uint64_t));
     rpy_revdb.buf_p += sizeof(uint64_t);
     flush_buffer();
-    _RPY_REVDB_UNLOCK();
 }
 
 RPY_EXTERN
 void rpy_reverse_db_lock_acquire(void)
 {
+    uint64_t pself;
     assert(!RPY_RDB_REPLAY);
     while (1) {
         if (rpy_revdb.lock == 0) {
@@ -345,7 +346,9 @@
     *rpy_active_thread_ptr = 0;
     rpy_active_thread = 1;
     rpy_active_thread_ptr = &rpy_active_thread;
-    emit_async_block(ASYNC_THREAD_SWITCH, (uint64_t)pthread_self());
+    pself = (uint64_t)pthread_self();
+    emit_async_block(ASYNC_THREAD_SWITCH, pself);
+    _RPY_REVDB_PRINT("[THRD]", pself);
 }
 
 static void record_stop_point(void)
@@ -362,7 +365,9 @@
     int64_t done;
 
     /* Write an ASYNC_FINALIZER_TRIGGER packet */
+    _RPY_REVDB_LOCK();
     emit_async_block(ASYNC_FINALIZER_TRIGGER, rpy_revdb.stop_point_seen);
+    _RPY_REVDB_UNLOCK();
 
     /* Invoke all Boehm finalizers.  For new-style finalizers, this
        will only cause them to move to the queues, where
@@ -854,6 +859,18 @@
     /* rpy_revdb.buf_limit is not set */
 }
 
+static uint64_t fetch_async_block(void)
+{
+    ssize_t full_packet_size = sizeof(int16_t) + sizeof(int64_t);
+    ssize_t keep = rpy_revdb.buf_readend - rpy_revdb.buf_p;
+    uint64_t result;
+    if (keep < full_packet_size)
+        fetch_more(keep, full_packet_size);
+    memcpy(&result, rpy_revdb.buf_p + sizeof(int16_t), sizeof(int64_t));
+    rpy_revdb.buf_p += full_packet_size;
+    return result;
+}
+
 RPY_EXTERN
 void rpy_reverse_db_fetch(const char *file, int line)
 {
@@ -871,6 +888,7 @@
             exit(1);
         }
 
+     read_next_packet:
         keep = rpy_revdb.buf_readend - rpy_revdb.buf_p;
         assert(keep >= 0);
 
@@ -892,11 +910,7 @@
                                     "ASYNC_FINALIZER_TRIGGER\n");
                     exit(1);
                 }
-                full_packet_size = sizeof(int16_t) + sizeof(int64_t);
-                if (keep < full_packet_size)
-                    fetch_more(keep, full_packet_size);
-                memcpy(&bp, rpy_revdb.buf_p + sizeof(int16_t), 
sizeof(int64_t));
-                rpy_revdb.buf_p += full_packet_size;
+                bp = fetch_async_block();
                 if (bp <= rpy_revdb.stop_point_seen) {
                     fprintf(stderr, "invalid finalizer break point\n");
                     exit(1);
@@ -908,6 +922,10 @@
                 rpy_revdb.buf_limit = rpy_revdb.buf_p;
                 return;
 
+            case ASYNC_THREAD_SWITCH:
+                fetch_async_block();
+                goto read_next_packet;
+
             default:
                 fprintf(stderr, "bad packet header %d\n", (int)header);
                 exit(1);
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
@@ -35,8 +35,8 @@
 #  define _RPY_REVDB_PRINT(mode, _e)                                    \
     if (rpy_rev_fileno >= 0) {                                          \
         fprintf(stderr,                                                 \
-                "%s:%d: %0*llx\n",                                      \
-                __FILE__, __LINE__, 2 * sizeof(_e),                     \
+                "%s %s:%d: %0*llx\n",                                   \
+                mode, __FILE__, __LINE__, 2 * sizeof(_e),               \
                 ((unsigned long long)_e) & ((2ULL << (8*sizeof(_e)-1)) - 1)); \
     }
 #endif
@@ -47,7 +47,7 @@
     if (rpy_rev_fileno >= 0) {                                          \
         seeing_uid(uid);                                                \
         fprintf(stderr,                                                 \
-                "%s:%d: obj %llu\n",                                    \
+                "[nobj] %s:%d: obj %llu\n",                             \
                 __FILE__, __LINE__, (unsigned long long) uid);          \
     }
 #endif
@@ -76,7 +76,7 @@
 #define _RPY_REVDB_EMIT_RECORD_L(decl_e, variable)                      \
         {                                                               \
             decl_e = variable;                                          \
-            _RPY_REVDB_PRINT("write", _e);                              \
+            _RPY_REVDB_PRINT("[ wr ]", _e);                             \
             memcpy(rpy_revdb.buf_p, &_e, sizeof(_e));                   \
             if ((rpy_revdb.buf_p += sizeof(_e)) > rpy_revdb.buf_limit)  \
                 rpy_reverse_db_flush();                                 \
@@ -89,7 +89,7 @@
             char *_end1 = _src + sizeof(_e);                            \
             memcpy(&_e, _src, sizeof(_e));                              \
             rpy_revdb.buf_p = _end1;                                    \
-            _RPY_REVDB_PRINT("read", _e);                               \
+            _RPY_REVDB_PRINT("[read]", _e);                             \
             if (_end1 >= rpy_revdb.buf_limit)                           \
                 rpy_reverse_db_fetch(__FILE__, __LINE__);               \
             variable = _e;                                              \
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
@@ -13,6 +13,9 @@
 from rpython.translator.revdb.process import ReplayProcess
 
 
+ASYNC_THREAD_SWITCH = 0xff54 - 2**16
+
+
 class RDB(object):
     def __init__(self, filename, expected_argv):
         with open(filename, 'rb') as f:
@@ -30,6 +33,7 @@
         self.argc = self.read1('i')
         self.argv = self.read1('P')
         self.current_packet_end = self.cur
+        self.main_thread_id = self.switch_thread()
         self.read_check_argv(expected_argv)
 
     def read1(self, mode):
@@ -95,15 +99,22 @@
     def same_stack(self):
         x = self.next('c'); assert x == '\xFC'
 
+    def switch_thread(self, expected=None):
+        th, = self.special_packet(ASYNC_THREAD_SWITCH, 'q')
+        if expected is not None:
+            assert th == expected
+        return th
+
 
 def compile(self, entry_point, backendopt=True,
-            withsmallfuncsets=None, shared=False):
+            withsmallfuncsets=None, shared=False, thread=False):
     t = Translation(entry_point, None, gc="boehm")
     self.t = t
     t.set_backend_extra_options(c_debug_defines=True)
     t.config.translation.reverse_debugger = True
     t.config.translation.lldebug0 = True
     t.config.translation.shared = shared
+    t.config.translation.thread = thread
     if withsmallfuncsets is not None:
         t.config.translation.withsmallfuncsets = withsmallfuncsets
     if not backendopt:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to