[pypy-commit] pypy reverse-debugger: in-progress
arigo
pypy.commits at gmail.com
Sun Jun 5 11:46:19 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r84939:b7e8d7232049
Date: 2016-06-05 17:47 +0200
http://bitbucket.org/pypy/pypy/changeset/b7e8d7232049/
Log: in-progress
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
@@ -2,7 +2,7 @@
from rpython.translator.c.support import cdecl
from rpython.translator.c.support import llvalue_from_constant, gen_assignments
from rpython.translator.c.support import c_string_constant, barebonearray
-from rpython.translator.c.primitive import PRIMITIVE_FLOATS
+from rpython.translator.c.primitive import PRIMITIVE_FLOATS, PRIMITIVE_TWO_LONGS
from rpython.flowspace.model import Variable, Constant
from rpython.rtyper.lltypesystem.lltype import (Ptr, Void, Bool, Signed, Unsigned,
SignedLongLong, Float, UnsignedLongLong, Char, UniChar, ContainerType,
@@ -430,6 +430,8 @@
return '/* rpy_reverse_db_emit_void(%s); */' % (value,)
elif T in PRIMITIVE_FLOATS:
return 'rpy_reverse_db_emit_float(%s);' % (value,)
+ elif T in PRIMITIVE_TWO_LONGS:
+ return 'rpy_reverse_db_emit_two_longs(%s);' % (value,)
else:
return 'rpy_reverse_db_emit((Signed)%s);' % (value,)
@@ -441,7 +443,8 @@
if T is Void:
result = '/* %s */' % result
if self.db.reversedb:
- if self.lltypemap(op.args[0]).TO._gckind != 'gc':
+ S = self.lltypemap(op.args[0]).TO
+ if S._gckind != 'gc' and not S._hints.get('is_excdata'):
result += '\t' + self._reverse_db_emit(T, newvalue)
return result
diff --git a/rpython/translator/c/primitive.py b/rpython/translator/c/primitive.py
--- a/rpython/translator/c/primitive.py
+++ b/rpython/translator/c/primitive.py
@@ -224,6 +224,10 @@
GCREF: name_gcref,
}
PRIMITIVE_FLOATS = set([Float, SingleFloat, LongFloat])
+if SignedLongLong is Signed:
+ PRIMITIVE_TWO_LONGS = set([])
+else:
+ PRIMITIVE_TWO_LONGS = set([SignedLongLong, UnsignedLongLong])
PrimitiveType = {
SignedLongLong: 'long long @',
diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py
--- a/rpython/translator/exceptiontransform.py
+++ b/rpython/translator/exceptiontransform.py
@@ -452,7 +452,8 @@
def setup_excdata(self):
EXCDATA = lltype.Struct('ExcData',
('exc_type', self.lltype_of_exception_type),
- ('exc_value', self.lltype_of_exception_value))
+ ('exc_value', self.lltype_of_exception_value),
+ hints={'is_excdata': True})
self.EXCDATA = EXCDATA
exc_data = lltype.malloc(EXCDATA, immortal=True)
diff --git a/rpython/translator/reversedb/rdb-src/rdb.c b/rpython/translator/reversedb/rdb-src/rdb.c
--- a/rpython/translator/reversedb/rdb-src/rdb.c
+++ b/rpython/translator/reversedb/rdb-src/rdb.c
@@ -21,29 +21,29 @@
/* init-time setup */
char *filename = getenv("PYPYRDB");
- if (filename && *filename)
- putenv("PYPYRDB=");
- else
- filename = "/dev/null";
-
- rpy_rev_fileno = open(filename, O_WRONLY | O_CLOEXEC |
- O_CREAT | O_NOCTTY | O_TRUNC, 0600);
- if (rpy_rev_fileno < 0) {
- fprintf(stderr, "Fatal error: can't create PYPYRDB file '%s'\n",
- filename);
- abort();
- }
rpy_rev_buf_p = rpy_rev_buffer;
rpy_rev_buf_end = rpy_rev_buffer +
sizeof(rpy_rev_buffer) / sizeof(rpy_rev_buffer[0]);
- atexit(rpy_reverse_db_flush);
+
+ if (filename && *filename) {
+ putenv("PYPYRDB=");
+ rpy_rev_fileno = open(filename, O_WRONLY | O_CLOEXEC |
+ O_CREAT | O_NOCTTY | O_TRUNC, 0600);
+ if (rpy_rev_fileno < 0) {
+ fprintf(stderr, "Fatal error: can't create PYPYRDB file '%s'\n",
+ filename);
+ abort();
+ }
+ atexit(rpy_reverse_db_flush);
+ }
rpy_reverse_db_emit(RDB_SIGNATURE);
rpy_reverse_db_emit(RDB_VERSION);
rpy_reverse_db_emit(0);
rpy_reverse_db_emit(0);
rpy_reverse_db_emit(argc);
+ rpy_reverse_db_emit((Signed)argv);
}
RPY_EXTERN
@@ -53,8 +53,10 @@
ssize_t size = (rpy_rev_buf_p - rpy_rev_buffer) * sizeof(rpy_rev_buffer[0]);
rpy_rev_buf_p = rpy_rev_buffer;
- if (size > 0 && write(rpy_rev_fileno, rpy_rev_buffer, size) != size) {
- fprintf(stderr, "Fatal error: writing to PYPYRDB file: %m\n");
- abort();
+ if (size > 0 && rpy_rev_fileno >= 0) {
+ if (write(rpy_rev_fileno, rpy_rev_buffer, size) != size) {
+ fprintf(stderr, "Fatal error: writing to PYPYRDB file: %m\n");
+ abort();
+ }
}
}
diff --git a/rpython/translator/reversedb/rdb-src/rdb_include.h b/rpython/translator/reversedb/rdb-src/rdb_include.h
--- a/rpython/translator/reversedb/rdb-src/rdb_include.h
+++ b/rpython/translator/reversedb/rdb-src/rdb_include.h
@@ -1,4 +1,4 @@
-
+#include <string.h>
RPY_EXTERN void rpy_reverse_db_setup(int argc, char *argv[]);
RPY_EXTERN void rpy_reverse_db_flush(void);
@@ -12,12 +12,21 @@
if (rpy_rev_buf_p == rpy_rev_buf_end)
rpy_reverse_db_flush();
}
+
static inline void rpy_reverse_db_emit_float(double value) {
/* xxx for 'long double' this can loose some precision */
- Signed sval[8 / SIZEOF_LONG];
- assert(sizeof(double) == 8);
+ Signed sval[sizeof(double) / SIZEOF_LONG];
memcpy(sval, &value, sizeof(value));
rpy_reverse_db_emit(sval[0]);
- if (SIZEOF_LONG <= 4)
+ if (SIZEOF_LONG < sizeof(double)) /* assume len(sval) is exactly 1 or 2 */
rpy_reverse_db_emit(sval[1]);
}
+
+static inline void rpy_reverse_db_emit_two_longs(long long value)
+{
+ Signed sval[2];
+ assert(SIZEOF_LONG * 2 == SIZEOF_LONG_LONG);
+ memcpy(sval, &value, sizeof(value));
+ rpy_reverse_db_emit(sval[0]);
+ rpy_reverse_db_emit(sval[1]);
+}
diff --git a/rpython/translator/reversedb/test/test_basic.py b/rpython/translator/reversedb/test/test_basic.py
--- a/rpython/translator/reversedb/test/test_basic.py
+++ b/rpython/translator/reversedb/test/test_basic.py
@@ -1,7 +1,34 @@
import py
+import os
+import array, struct
+from rpython.tool.udir import udir
from rpython.translator.interactive import Translation
+class RDB(object):
+ def __init__(self, filename):
+ f = open(filename, 'rb')
+ f.seek(0, 2)
+ filesize = f.tell()
+ f.seek(0, 0)
+ self.items = array.array("l")
+ self.items.fromfile(f, filesize / struct.calcsize("l"))
+ f.close()
+ #
+ assert self.items[0] == 0x0A424452
+ assert self.items[1] == 0x00FF0001
+ assert self.items[2] == 0
+ assert self.items[3] == 0
+ self.argc = self.items[4]
+ self.argv = self.items[5]
+ self.cur = 6
+
+ def next(self):
+ n = self.cur
+ self.cur = n + 1
+ return self.items[n]
+
+
class TestBasic(object):
def getcompiled(self, entry_point, argtypes, backendopt=True):
@@ -14,16 +41,42 @@
t.rtype()
if t.backendopt:
t.backendopt()
- t.compile_c()
+ self.exename = t.compile_c()
+ self.rdbname = os.path.join(os.path.dirname(str(self.exename)),
+ 'log.rdb')
def run(*argv):
- stdout = t.driver.cbuilder.cmdexec(' '.join(argv))
+ env = os.environ.copy()
+ env['PYPYRDB'] = self.rdbname
+ stdout = t.driver.cbuilder.cmdexec(' '.join(argv), env=env)
return stdout
return run
+ def fetch_rdb(self):
+ return RDB(self.rdbname)
+
def test_simple(self):
def main(argv):
print argv[1:]
return 0
fn = self.getcompiled(main, [], backendopt=False)
assert fn('abc d') == '[abc, d]\n'
+ rdb = self.fetch_rdb()
+ assert rdb.argc == 3
+ #
+ got = []
+ for i in range(3):
+ rdb.next() # ignore the address of argv[i]
+ s = []
+ while True:
+ c = rdb.next()
+ if c == 0:
+ break
+ s.append(chr(c))
+ for c1 in s:
+ c2 = rdb.next()
+ assert c2 == ord(c1)
+ got.append(''.join(s))
+ assert rdb.cur == len(rdb.items)
+ #
+ assert got == [self.exename, 'abc', 'd']
More information about the pypy-commit
mailing list