[pypy-commit] pypy reverse-debugger: push and pull to get it to shape for the next step (which involves fork)
arigo
pypy.commits at gmail.com
Tue Jun 7 15:19:33 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r85009:9734700e55f1
Date: 2016-06-07 21:20 +0200
http://bitbucket.org/pypy/pypy/changeset/9734700e55f1/
Log: push and pull to get it to shape for the next step (which involves
fork)
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,14 +15,10 @@
static char rpy_rev_buffer[16384];
static int rpy_rev_fileno = -1;
-#ifndef rpy_rdb_replay
-bool_t rpy_rdb_replay;
-#endif
-
static void setup_record_mode(int argc, char *argv[]);
static void setup_replay_mode(int *argc_p, char **argv_p[]);
-static void check_at_end(int exitcode, int *exitcode_p);
+static void check_at_end(int exitcode, int *exitcode_p, uint64_t stop_points);
RPY_EXTERN
void rpy_reverse_db_setup(int *argc_p, char **argv_p[])
@@ -31,17 +27,17 @@
int replay_asked = (*argc_p >= 2 && !strcmp((*argv_p)[1], "--replay"));
-#ifdef rpy_rdb_replay
- if (replay_asked != rpy_rdb_replay) {
+#ifdef RPY_RDB_DYNAMIC_REPLAY
+ RPY_RDB_REPLAY = replay_asked;
+#else
+ if (replay_asked != RPY_RDB_REPLAY) {
fprintf(stderr, "This executable was only compiled for %s mode.",
- rpy_rdb_replay ? "replay" : "record");
+ RPY_RDB_REPLAY ? "replay" : "record");
exit(1);
}
-#else
- rpy_rdb_replay = replay_asked;
#endif
- if (rpy_rdb_replay)
+ if (RPY_RDB_REPLAY)
setup_replay_mode(argc_p, argv_p);
else
setup_record_mode(*argc_p, *argv_p);
@@ -51,12 +47,15 @@
void rpy_reverse_db_teardown(int *exitcode_p)
{
int exitcode;
+ uint64_t stop_points;
RPY_REVDB_EMIT(exitcode = *exitcode_p; , int _e, exitcode);
+ RPY_REVDB_EMIT(stop_points = rpy_revdb.stop_point_seen; ,
+ uint64_t _e, stop_points);
- if (!rpy_rdb_replay)
+ if (!RPY_RDB_REPLAY)
rpy_reverse_db_flush();
else
- check_at_end(exitcode, exitcode_p);
+ check_at_end(exitcode, exitcode_p, stop_points);
}
@@ -70,7 +69,7 @@
char *filename = getenv("PYPYREVDB");
Signed x;
- assert(!rpy_rdb_replay);
+ assert(RPY_RDB_REPLAY == 0);
rpy_revdb.buf_p = rpy_rev_buffer;
rpy_revdb.buf_limit = rpy_rev_buffer + sizeof(rpy_rev_buffer) - 32;
@@ -132,19 +131,23 @@
static void setup_replay_mode(int *argc_p, char **argv_p[])
{
Signed x;
- char *filename = (*argc_p) <= 2 ? "-" : (*argv_p)[2];
+ int argc = *argc_p;
+ char **argv = *argv_p;
+ char *filename;
- if (!strcmp(filename, "-")) {
- rpy_rev_fileno = 0; /* stdin */
+ if (argc != 3) {
+ fprintf(stderr, "syntax: %s --replay <RevDB-file>\n", argv[0]);
+ exit(2);
}
- else {
- 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);
- }
+ filename = argv[2];
+
+ 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);
}
- assert(rpy_rdb_replay);
+
+ assert(RPY_RDB_REPLAY == 1);
rpy_revdb.buf_p = rpy_rev_buffer;
rpy_revdb.buf_limit = rpy_rev_buffer;
@@ -171,13 +174,15 @@
RPY_REVDB_EMIT(abort();, Signed _e, x);
*argv_p = (char **)x;
+
+ rpy_revdb.stop_point_break = 1;
}
-static void check_at_end(int exitcode, int *exitcode_p)
+static void check_at_end(int exitcode, int *exitcode_p, uint64_t stop_points)
{
char dummy[1];
- if (*exitcode_p != exitcode) {
- fprintf(stderr, "Bogus exit code\n");
+ if (stop_points != rpy_revdb.stop_point_seen) {
+ fprintf(stderr, "Bad number of stop points\n");
exit(1);
}
if (rpy_revdb.buf_p != rpy_revdb.buf_limit ||
@@ -185,8 +190,12 @@
fprintf(stderr, "RevDB file error: corrupted file (too much data?)\n");
exit(1);
}
- printf("Replaying finished.\n");
- rpy_reverse_db_stop_point(0);
+ if (*exitcode_p != exitcode) {
+ fprintf(stderr, "Bogus exit code\n");
+ exit(1);
+ }
+ printf("Replaying finished (exit code %d)\n", exitcode);
+ rpy_reverse_db_break(0);
*exitcode_p = 0;
}
@@ -219,9 +228,10 @@
}
RPY_EXTERN
-void rpy_reverse_db_stop_point(long stop_point)
+void rpy_reverse_db_break(long stop_point)
{
- printf("stop_point %ld\n", stop_point);
+ printf("break #%ld after %lld stop points\n", stop_point,
+ (long long)rpy_revdb.stop_point_seen);
}
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,29 +1,36 @@
#include <string.h>
+#include <stdint.h>
+
+/* By default, this makes an executable which supports both recording
+ and replaying. It should help avoid troubles like using for
+ replaying an executable that is slightly different than the one
+ used for recording. In theory you can compile with
+ -DRPY_RDB_REPLAY=0 or -DRPY_RDB_REPLAY=1 to get only one version
+ compiled for it, which should be slightly faster (not tested so
+ far).
+*/
+
+typedef struct {
+#ifndef RPY_RDB_REPLAY
+ bool_t replay;
+#define RPY_RDB_REPLAY rpy_revdb.replay
+#define RPY_RDB_DYNAMIC_REPLAY
+#endif
+ char *buf_p, *buf_limit;
+ uint64_t stop_point_seen, stop_point_break;
+} rpy_revdb_t;
+
+RPY_EXTERN rpy_revdb_t rpy_revdb;
+
+
+/* ------------------------------------------------------------ */
RPY_EXTERN void rpy_reverse_db_setup(int *argc_p, char **argv_p[]);
RPY_EXTERN void rpy_reverse_db_teardown(int *exitcode_p);
-typedef struct { char *buf_p, *buf_limit; } rpy_revdb_t;
-RPY_EXTERN rpy_revdb_t rpy_revdb;
-
-
-/* By default, this makes an executable which supports both recording
- and replaying. It should help avoid troubles like using for
- replaying an executable that is slightly different than the one
- used for recording. In theory you can compile with
- -Drpy_rdb_replay=0 or -Drpy_rdb_replay=1 to get only one version
- compiled it (not tested so far).
-*/
-#ifndef rpy_rdb_replay
-RPY_EXTERN bool_t rpy_rdb_replay;
-#endif
-
-
-/* ------------------------------------------------------------ */
-
#define RPY_REVDB_EMIT(normal_code, decl_e, variable) \
- if (!rpy_rdb_replay) { \
+ if (!RPY_RDB_REPLAY) { \
normal_code \
{ \
decl_e = variable; \
@@ -45,14 +52,15 @@
}
#define RPY_REVDB_EMIT_VOID(normal_code) \
- if (!rpy_rdb_replay) { normal_code } else { }
+ if (!RPY_RDB_REPLAY) { normal_code } else { }
#define OP_REVDB_STOP_POINT(stop_point, r) \
- if (rpy_rdb_replay) rpy_reverse_db_stop_point(stop_point);
+ if (++rpy_revdb.stop_point_seen == rpy_revdb.stop_point_break) \
+ rpy_reverse_db_break(stop_point);
RPY_EXTERN void rpy_reverse_db_flush(void);
RPY_EXTERN char *rpy_reverse_db_fetch(int expected_size);
-RPY_EXTERN void rpy_reverse_db_stop_point(long stop_point);
+RPY_EXTERN void rpy_reverse_db_break(long stop_point);
/* ------------------------------------------------------------ */
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
@@ -25,6 +25,9 @@
self.cur = p + struct.calcsize(mode)
return struct.unpack_from(mode, self.buffer, p)[0]
+ def number_of_stop_points(self):
+ return struct.unpack_from("q", self.buffer, len(self.buffer) - 8)[0]
+
def done(self):
return self.cur == len(self.buffer)
@@ -91,6 +94,7 @@
x = rdb.next(); assert x == len('[abc, d]\n')
x = rdb.next('i'); assert x == 0 # errno
x = rdb.next('i'); assert x == 9 # exitcode
+ x = rdb.next('q'); assert x == 0 # number of stop points
# that's all that should get from this simple example
assert rdb.done()
#
@@ -98,8 +102,8 @@
#
# Now try the replay mode (just "doesn't crash" for now)
out = replay()
- assert out == ("Replaying finished.\n"
- "stop_point 0\n")
+ assert out == ("Replaying finished (exit code 9)\n"
+ "break #0 after 0 stop points\n")
def test_simple_interpreter(self):
def main(argv):
@@ -108,9 +112,9 @@
print op
return 9
fn, replay = self.getcompiled(main, [], backendopt=False)
- assert fn('abc d') == 'abc\nd\n'
+ assert fn('abc d ef') == 'abc\nd\nef\n'
+ assert self.fetch_rdb().number_of_stop_points() == 3
out = replay()
- assert out == ("stop_point 42\n"
- "stop_point 42\n"
- "Replaying finished.\n"
- "stop_point 0\n")
+ assert out == ("break #42 after 1 stop points\n"
+ "Replaying finished (exit code 9)\n"
+ "break #0 after 3 stop points\n")
More information about the pypy-commit
mailing list