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