Author: Armin Rigo <ar...@tunes.org> Branch: reverse-debugger Changeset: r86128:33ad82b0c795 Date: 2016-08-10 09:25 +0200 http://bitbucket.org/pypy/pypy/changeset/33ad82b0c795/
Log: fixes diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -203,7 +203,8 @@ # use generate_source(defines=DEBUG_DEFINES) to force the #definition # of the macros that enable debugging assertions DEBUG_DEFINES = {'RPY_ASSERT': 1, - 'RPY_LL_ASSERT': 1} + 'RPY_LL_ASSERT': 1, + 'RPY_REVDB_PRINT_ALL': 1} def generate_source(self, db=None, defines={}, exe_name=None): assert self.c_source_filename is None 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 @@ -83,9 +83,18 @@ return call_code # a hack for ll_call_destructor() to mean # that the calls should really be done # - # hack: we don't need the flag for at least these two common functions - if call_code in ('RPyGilRelease();', 'RPyGilAcquire();'): + # hack: we don't need the flag for at least this common function + if call_code == 'RPyGilRelease();': return 'RPY_REVDB_CALL_GILCTRL(%s);' % (call_code,) + if call_code == 'RPyGilAcquire();': + # Could also work with a regular RPY_REVDB_CALL_VOID, but we + # use a different byte (0xFD instead of 0xFC) to detect more + # sync misses. In a single-threaded environment this 0xFD + # byte is not needed at all, but in a multi-threaded + # environment it ensures that during replaying, we don't go + # past the RPyGilAcquire() in case a different thread must run + # next. + return 'RPY_REVDB_CALL_GIL(%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 @@ -1526,6 +1526,13 @@ } while (e != 0xFC); } +RPY_EXTERN +void rpy_reverse_db_bad_acquire_gil(void) +{ + fprintf(stderr, "out of sync: unexpected byte in log (at acquire_gil)\n"); + 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 @@ -31,7 +31,8 @@ RPY_EXTERN void rpy_reverse_db_setup(int *argc_p, char **argv_p[]); RPY_EXTERN void rpy_reverse_db_teardown(void); -#if 0 /* enable to print locations to stderr of all the EMITs */ +/* enable to print locations to stderr of all the EMITs */ +#ifdef RPY_REVDB_PRINT_ALL # define _RPY_REVDB_PRINT(mode, _e) \ if (rpy_rev_fileno >= 0) { \ fprintf(stderr, \ @@ -41,7 +42,8 @@ } #endif -#if 0 /* enable to print all mallocs to stderr */ +/* enable to print all mallocs to stderr */ +#ifdef RPY_REVDB_PRINT_ALL RPY_EXTERN void seeing_uid(uint64_t uid); # define _RPY_REVDB_PRUID() \ if (rpy_rev_fileno >= 0) { \ @@ -140,6 +142,20 @@ rpy_reverse_db_invoke_callback(_re); \ } +#define RPY_REVDB_CALL_GIL(call_code) \ + if (!RPY_RDB_REPLAY) { \ + call_code \ + _RPY_REVDB_LOCK(); \ + _RPY_REVDB_EMIT_RECORD_L(unsigned char _e, 0xFD) \ + _RPY_REVDB_UNLOCK(); \ + } \ + else { \ + unsigned char _re; \ + _RPY_REVDB_EMIT_REPLAY(unsigned char _e, _re) \ + if (_re != 0xFD) \ + rpy_reverse_db_bad_acquire_gil(); \ + } + #define RPY_REVDB_CALL_GILCTRL(call_code) \ if (!RPY_RDB_REPLAY) { \ call_code \ @@ -223,5 +239,6 @@ RPY_EXTERN void rpy_reverse_db_invoke_callback(unsigned char); RPY_EXTERN void rpy_reverse_db_callback_loc(int); RPY_EXTERN void rpy_reverse_db_lock_acquire(bool_t lock_contention); +RPY_EXTERN void rpy_reverse_db_bad_acquire_gil(void); /* ------------------------------------------------------------ */ 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 @@ -95,10 +95,14 @@ x = self.next(); assert x == len(expected_string) self.same_stack() # errno x = self.next('i'); assert x == 0 # errno + self.gil_acquire() def same_stack(self): x = self.next('c'); assert x == '\xFC' + def gil_acquire(self): + x = self.next('c'); assert x == '\xFD' + def switch_thread(self, expected=None): th, = self.special_packet(ASYNC_THREAD_SWITCH, 'q') if expected is not None: 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 @@ -65,13 +65,17 @@ rdb = self.fetch_rdb([self.exename, 'Xx']) rdb.same_stack() # callmesimple() x = rdb.next('i'); assert x == 55555 + rdb.gil_acquire() rdb.write_call('55555\n') b = rdb.next('!h'); assert 300 <= b < 310 # -> callback x = rdb.next('i'); assert x == 40 # arg n + rdb.gil_acquire() x = rdb.next('!h'); assert x == b # -> callback x = rdb.next('i'); assert x == 3 # arg n + rdb.gil_acquire() rdb.same_stack() # <- return in main thread x = rdb.next('i'); assert x == 4000 * 300 # return from callme() + rdb.gil_acquire() rdb.write_call('%s\n' % (4000 * 300,)) x = rdb.next('q'); assert x == 0 # number of stop points assert rdb.done() @@ -83,12 +87,15 @@ rdb = self.fetch_rdb([self.exename, 'Xx']) b = rdb.next('!h'); assert 300 <= b < 310 # -> callback x = rdb.next('i'); assert x == 40 # arg n + rdb.gil_acquire() rdb.write_call('40\n') x = rdb.next('!h'); assert x == b # -> callback again x = rdb.next('i'); assert x == 3 # arg n + rdb.gil_acquire() rdb.write_call('3\n') rdb.same_stack() # -> return in main thread x = rdb.next('i'); assert x == 120 # <- return from callme() + rdb.gil_acquire() rdb.write_call('120\n') x = rdb.next('q'); assert x == 2 # number of stop points assert rdb.done() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit