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

Reply via email to