Author: Armin Rigo <ar...@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'] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit