Author: Armin Rigo <ar...@tunes.org>
Branch: reverse-debugger
Changeset: r88150:35cfe4e08de5
Date: 2016-11-06 09:12 +0100
http://bitbucket.org/pypy/pypy/changeset/35cfe4e08de5/

Log:    Issue #2429: be more careful in compute_unique_id().

diff --git a/rpython/translator/revdb/src-revdb/revdb.c 
b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -423,6 +423,39 @@
     return obj->h_hash;
 }
 
+RPY_EXTERN
+Signed rpy_reverse_db_cast_ptr_to_int(struct pypy_header0 *obj)
+{
+    /* Returns the "id" of the object.  Should return a unique number
+       among all objects, including prebuilt ones.
+    */
+    if (obj->h_uid == 0) {
+        /* prebuilt object: the object address is good enough, because
+           such addresses should not change between recording and
+           replaying.  The address is even and non-null, so the
+           following formula gives a unique negative result.
+        */
+        return (Signed)(-(((Unsigned)obj) >> 1));
+    }
+    else {
+        /* regular object: for now, may fail to work on 32-bit, where
+           h_uid is a 64-bit number that may grow bigger than 31 bits
+           if the program runs for long enough.  Print a warning if it
+           is the case. */
+        if (((Signed)(obj->h_uid)) != obj->h_uid) {
+            static int warning_printed = 0;
+            if (!warning_printed) {
+                fprintf(stderr, "WARNING: the program executes for long enough 
"
+                                "that it creates more than 2**31 objects.  In "
+                                "this situation, the id() function may return "
+                                "non-unique results.\n");
+                warning_printed = 1;
+            }
+        }
+        return (Signed)(obj->h_uid);
+    }
+}
+
 static uint64_t recording_offset(void)
 {
     /* must be called with the lock held */
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h 
b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -231,10 +231,8 @@
 #define OP_REVDB_CALL_DESTRUCTOR(obj, r)                                \
     rpy_reverse_db_call_destructor(obj)
 
-/* Used only for getting a fast hash value that doesn't change too
-   often (with the minimark GC, it changes at most once).  Here,
-   we'll just return the UID. */
-#define RPY_REVDB_CAST_PTR_TO_INT(obj)   (((struct pypy_header0 *)obj)->h_uid)
+#define RPY_REVDB_CAST_PTR_TO_INT(obj)                                  \
+    rpy_reverse_db_cast_ptr_to_int((struct pypy_header0 *)(obj))
 
 #define OP_REVDB_SET_THREAD_BREAKPOINT(tnum, r)                         \
     rpy_reverse_db_set_thread_breakpoint(tnum)
@@ -279,6 +277,7 @@
 RPY_EXTERN void rpy_reverse_db_send_answer(int cmd, int64_t arg1, int64_t arg2,
                                            int64_t arg3, RPyString *extra);
 RPY_EXTERN Signed rpy_reverse_db_identityhash(struct pypy_header0 *obj);
+RPY_EXTERN Signed rpy_reverse_db_cast_ptr_to_int(struct pypy_header0 *obj);
 RPY_EXTERN void rpy_reverse_db_breakpoint(int64_t num);
 RPY_EXTERN long long rpy_reverse_db_get_value(char value_id);
 RPY_EXTERN uint64_t rpy_reverse_db_unique_id_break(void *new_object);
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to