Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit