Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit