Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit