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