[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