[pypy-commit] pypy reverse-debugger: in-progress
arigo
pypy.commits at gmail.com
Tue Aug 9 12:05:55 EDT 2016
Author: Armin Rigo <arigo at 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)
More information about the pypy-commit
mailing list