Author: Armin Rigo <ar...@tunes.org> Branch: reverse-debugger Changeset: r84963:db02f646172a Date: 2016-06-06 12:28 +0200 http://bitbucket.org/pypy/pypy/changeset/db02f646172a/
Log: in-progress: replay mode diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -400,7 +400,7 @@ break elif self.db.reverse_debugger: from rpython.translator.revdb import revdb_genc - line += '\n' + revdb_genc.emit(self.lltypename(v_result), r) + line = revdb_genc.emit(line, self.lltypename(v_result), r) return line def OP_DIRECT_CALL(self, op): @@ -440,8 +440,8 @@ S = self.lltypemap(op.args[0]).TO if S._gckind != 'gc' and not S._hints.get('is_excdata'): from rpython.translator.revdb import revdb_genc - result += '\t' + revdb_genc.emit(self.lltypename(op.result), - newvalue) + result = revdb_genc.emit(result, self.lltypename(op.result), + newvalue) return result def generic_set(self, op, targetexpr): diff --git a/rpython/translator/c/src/entrypoint.c b/rpython/translator/c/src/entrypoint.c --- a/rpython/translator/c/src/entrypoint.c +++ b/rpython/translator/c/src/entrypoint.c @@ -37,6 +37,10 @@ # include <src/thread.h> #endif +#ifdef RPY_REVERSE_DEBUGGER +# include <rdb-src/revdb_include.h> +#endif + RPY_EXPORTED void rpython_startup_code(void) { @@ -83,7 +87,7 @@ instrument_setup(); #ifdef RPY_REVERSE_DEBUGGER - rpy_reverse_db_setup(argc, argv); + rpy_reverse_db_setup(&argc, &argv); #endif #ifndef MS_WINDOWS @@ -99,6 +103,10 @@ exitcode = STANDALONE_ENTRY_POINT(argc, argv); +#ifdef RPY_REVERSE_DEBUGGER + rpy_reverse_db_teardown(); +#endif + pypy_debug_alloc_results(); if (RPyExceptionOccurred()) { diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -187,9 +187,9 @@ rules = [ ('all', '$(DEFAULT_TARGET)', []), ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGSEXTRA) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) $(LINKFILES) $(LDFLAGS)'), - ('%.o', '%.c', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) -o $@ -c $< $(INCLUDEDIRS)'), - ('%.o', '%.s', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) -o $@ -c $< $(INCLUDEDIRS)'), - ('%.o', '%.cxx', '$(CXX) $(CFLAGS) $(CFLAGSEXTRA) -o $@ -c $< $(INCLUDEDIRS)'), + ('%.o', '%.c', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) $(CFLAGS1) -o $@ -c $< $(INCLUDEDIRS)'), + ('%.o', '%.s', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) $(CFLAGS1) -o $@ -c $< $(INCLUDEDIRS)'), + ('%.o', '%.cxx', '$(CXX) $(CFLAGS) $(CFLAGSEXTRA) $(CFLAGS1) -o $@ -c $< $(INCLUDEDIRS)'), ] for rule in rules: diff --git a/rpython/translator/revdb/rdb-src/revdb.c b/rpython/translator/revdb/rdb-src/revdb.c --- a/rpython/translator/revdb/rdb-src/revdb.c +++ b/rpython/translator/revdb/rdb-src/revdb.c @@ -15,12 +15,18 @@ static int rpy_rev_fileno = -1; +/* ------------------------------------------------------------ */ +#ifndef RPY_RDB_REPLAY +/* ------------------------------------------------------------ */ + + RPY_EXTERN -void rpy_reverse_db_setup(int argc, char *argv[]) +void rpy_reverse_db_setup(int *argc_p, char **argv_p[]) { /* init-time setup */ char *filename = getenv("PYPYREVDB"); + Signed x; rpy_revdb.buf_p = rpy_rev_buffer; rpy_revdb.buf_limit = rpy_rev_buffer + sizeof(rpy_rev_buffer) - 32; @@ -37,12 +43,18 @@ atexit(rpy_reverse_db_flush); } - rpy_reverse_db_EMIT(Signed _e=RDB_SIGNATURE); - rpy_reverse_db_EMIT(Signed _e=RDB_VERSION); - rpy_reverse_db_EMIT(Signed _e=0); - rpy_reverse_db_EMIT(Signed _e=0); - rpy_reverse_db_EMIT(Signed _e=argc); - rpy_reverse_db_EMIT(void *_e=argv); + RPY_REVDB_EMIT(x = RDB_SIGNATURE;, Signed _e, x); + RPY_REVDB_EMIT(x = RDB_VERSION;, Signed _e, x); + RPY_REVDB_EMIT(x = 0;, Signed _e, x); + RPY_REVDB_EMIT(x = 0;, Signed _e, x); + RPY_REVDB_EMIT(x = *argc_p;, Signed _e, x); + RPY_REVDB_EMIT(x = (Signed)*argv_p;, Signed _e, x); +} + +RPY_EXTERN +void rpy_reverse_db_teardown(void) +{ + rpy_reverse_db_flush(); } RPY_EXTERN @@ -59,3 +71,97 @@ } } } + + +/* ------------------------------------------------------------ */ +#else +/* ------------------------------------------------------------ */ + + +RPY_EXTERN +void rpy_reverse_db_setup(int *argc_p, char **argv_p[]) +{ + Signed x; + + if (*argc_p <= 1) { + rpy_rev_fileno = 0; /* stdin */ + } + else { + char *filename = (*argv_p)[1]; + rpy_rev_fileno = open(filename, O_RDONLY | O_NOCTTY); + if (rpy_rev_fileno < 0) { + fprintf(stderr, "Can't open file '%s': %m\n", filename); + exit(1); + } + } + rpy_revdb.buf_p = rpy_rev_buffer; + rpy_revdb.buf_limit = rpy_rev_buffer; + + RPY_REVDB_EMIT(*, Signed _e, x); + if (x != RDB_SIGNATURE) { + fprintf(stderr, "stdin is not a RevDB file (or wrong platform)\n"); + exit(1); + } + RPY_REVDB_EMIT(*, Signed _e, x); + if (x != RDB_VERSION) { + fprintf(stderr, "RevDB file version mismatch (got %lx, expected %lx)\n", + (long)x, (long)RDB_VERSION); + exit(1); + } + RPY_REVDB_EMIT(*, Signed _e, x); /* ignored */ + RPY_REVDB_EMIT(*, Signed _e, x); /* ignored */ + + RPY_REVDB_EMIT(*, Signed _e, x); + if (x <= 0) { + fprintf(stderr, "RevDB file is bogus\n"); + exit(1); + } + *argc_p = x; + + RPY_REVDB_EMIT(*, Signed _e, x); + *argv_p = (char **)x; +} + +RPY_EXTERN +void rpy_reverse_db_teardown(void) +{ + char dummy[1]; + if (rpy_revdb.buf_p != rpy_revdb.buf_limit || + read(rpy_rev_fileno, dummy, 1) > 0) { + fprintf(stderr, "RevDB file error: corrupted file (too much data?)\n"); + exit(1); + } +} + +RPY_EXTERN +char *rpy_reverse_db_fetch(int expected_size) +{ + ssize_t rsize, keep = rpy_revdb.buf_limit - rpy_revdb.buf_p; + assert(keep >= 0); + memmove(rpy_rev_buffer, rpy_revdb.buf_p, keep); + + retry: + rsize = read(rpy_rev_fileno, rpy_rev_buffer + keep, + sizeof(rpy_rev_buffer) - keep); + if (rsize <= 0) { + if (rsize == 0) + fprintf(stderr, "RevDB file appears truncated\n"); + else + fprintf(stderr, "RevDB file read error: %m\n"); + exit(1); + } + keep += rsize; + + rpy_revdb.buf_p = rpy_rev_buffer; + rpy_revdb.buf_limit = rpy_rev_buffer + keep; + + if (rpy_revdb.buf_limit - rpy_revdb.buf_p < expected_size) + goto retry; + + return rpy_rev_buffer; +} + + +/* ------------------------------------------------------------ */ +#endif +/* ------------------------------------------------------------ */ diff --git a/rpython/translator/revdb/rdb-src/revdb_include.h b/rpython/translator/revdb/rdb-src/revdb_include.h --- a/rpython/translator/revdb/rdb-src/revdb_include.h +++ b/rpython/translator/revdb/rdb-src/revdb_include.h @@ -1,15 +1,57 @@ #include <string.h> -RPY_EXTERN void rpy_reverse_db_setup(int argc, char *argv[]); -RPY_EXTERN void rpy_reverse_db_flush(void); - +RPY_EXTERN void rpy_reverse_db_setup(int *argc_p, char **argv_p[]); +RPY_EXTERN void rpy_reverse_db_teardown(void); typedef struct { char *buf_p, *buf_limit; } rpy_revdb_t; RPY_EXTERN rpy_revdb_t rpy_revdb; -#define rpy_reverse_db_EMIT(decl_e) do { \ - decl_e; \ - memcpy(rpy_revdb.buf_p, &_e, sizeof(_e)); \ - if ((rpy_revdb.buf_p += sizeof(_e)) > rpy_revdb.buf_limit) \ - rpy_reverse_db_flush(); \ -} while (0) + +/* ------------------------------------------------------------ */ +#ifndef RPY_RDB_REPLAY +/* ------------------------------------------------------------ */ + + +/* recording version of the macros */ +#define RPY_REVDB_EMIT(normal_code, decl_e, variable) \ + normal_code \ + do { \ + decl_e = variable; \ + memcpy(rpy_revdb.buf_p, &_e, sizeof(_e)); \ + if ((rpy_revdb.buf_p += sizeof(_e)) > rpy_revdb.buf_limit) \ + rpy_reverse_db_flush(); \ + } while (0) +#define RPY_REVDB_EMIT_VOID(normal_code) \ + normal_code + +RPY_EXTERN void rpy_reverse_db_flush(void); + + +/* ------------------------------------------------------------ */ +#else +/* ------------------------------------------------------------ */ + + +/* replaying version of the macros */ +#define RPY_REVDB_EMIT(normal_code, decl_e, variable) \ + do { \ + decl_e; \ + char *_src = rpy_revdb.buf_p; \ + char *_end1 = _src + sizeof(_e); \ + if (_end1 > rpy_revdb.buf_limit) { \ + _src = rpy_reverse_db_fetch(sizeof(_e)); \ + _end1 = _src + sizeof(_e); \ + } \ + rpy_revdb.buf_p = _end1; \ + memcpy(&_e, _src, sizeof(_e)); \ + variable = _e; \ + } while (0) +#define RPY_REVDB_EMIT_VOID(normal_code) \ + /* nothing */ + +RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size); + + +/* ------------------------------------------------------------ */ +#endif +/* ------------------------------------------------------------ */ diff --git a/rpython/translator/revdb/revdb_genc.py b/rpython/translator/revdb/revdb_genc.py --- a/rpython/translator/revdb/revdb_genc.py +++ b/rpython/translator/revdb/revdb_genc.py @@ -9,7 +9,7 @@ srcdir / 'revdb.c', ] -def emit(tp, value): +def emit(normal_code, tp, value): if tp == 'void @': - return '/* void */' - return 'rpy_reverse_db_EMIT(%s=%s);' % (cdecl(tp, '_e'), value) + return 'RPY_REVDB_EMIT_VOID(%s);' % (normal_code,) + return 'RPY_REVDB_EMIT(%s, %s, %s);' % (normal_code, cdecl(tp, '_e'), value) 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,3 +86,6 @@ assert rdb.done() # assert got == [self.exename, 'abc', 'd'] + # + # Now try the replay mode + xxx _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit