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