From: Paul Eggert Date: Fri, 27 Jul 2012 06:18:36 +0000 (-0700) Subject: Improve GDB symbol export. X-Git-Tag: emacs-24.2.90~1064 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4706125e2f5181d21c0e3b23b4aa5c96b21c3b67;p=emacs.git Improve GDB symbol export. * .gdbinit (xgetptr, xgetint, xgettype): Set $bugfix in different arms of an 'if', not using conditional expressions; otherwise GDB complains about the types in the unevaluated arm when the argument is an integer literal. (xgetint): Simplify expression. * alloc.c (gdb_make_enums_visible): New constant. This ports to GCC 3.4.2 the export of symbols to GDB. Problem reported by Eli Zaretskii in . * lisp.h (PUBLISH_TO_GDB): Remove. All uses removed. No longer needed now that we have gdb_make_enums_visible. (enum CHECK_LISP_OBJECT_TYPE, enum Lisp_Bits, enum More_Lisp_Bits) (enum enum_USE_LSB_TAG): New enum types, packaging up enums that need to be exported to GDB. --- diff --git a/src/.gdbinit b/src/.gdbinit index c044b404f9b..25b555b8540 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -46,17 +46,29 @@ handle SIGALRM ignore # Use $bugfix so that the value isn't a constant. # Using a constant runs into GDB bugs sometimes. define xgetptr - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end set $ptr = ($bugfix & VALMASK) | DATA_SEG_BITS end define xgetint - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 - set $int = USE_LSB_TAG ? $bugfix >> INTTYPEBITS : $bugfix << INTTYPEBITS >> INTTYPEBITS + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end + set $int = $bugfix << (USE_LSB_TAG ? 0 : INTTYPEBITS) >> INTTYPEBITS end define xgettype - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : $bugfix >> VALBITS) end diff --git a/src/ChangeLog b/src/ChangeLog index e1d0ef8e90e..cf90a35f230 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2012-07-27 Paul Eggert + + Improve GDB symbol export (Bug#12036). + * .gdbinit (xgetptr, xgetint, xgettype): Set $bugfix in different + arms of an 'if', not using conditional expressions; otherwise GDB + complains about the types in the unevaluated arm when the argument + is an integer literal. + (xgetint): Simplify expression. + * alloc.c (gdb_make_enums_visible): New constant. This ports to + GCC 3.4.2 the export of symbols to GDB. Problem reported by Eli + Zaretskii in . + * lisp.h (PUBLISH_TO_GDB): Remove. All uses removed. No longer + needed now that we have gdb_make_enums_visible. + (enum CHECK_LISP_OBJECT_TYPE, enum Lisp_Bits, enum More_Lisp_Bits) + (enum enum_USE_LSB_TAG): + New enum types, packaging up enums that need to be exported to GDB. + 2012-07-27 Dmitry Antipov Utility function to make a list from specified amount of objects. diff --git a/src/alloc.c b/src/alloc.c index 3d8b7a54d06..948ce7b6f5c 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6910,12 +6910,25 @@ The time is in seconds as a floating point value. */); #endif } -/* Make some symbols visible to GDB. These cannot be done as enums, like - GCTYPEBITS or USE_LSB_TAG, since values might not be in 'int' range. - Each symbol X has a corresponding X_VAL symbol, verified to have - the correct value. - - This is last, so that the #undef lines don't mess up later code. */ +/* Make some symbols visible to GDB. This section is last, so that + the #undef lines don't mess up later code. */ + +/* When compiled with GCC, GDB might say "No enum type named + pvec_type" if we don't have at least one symbol with that type, and + then xbacktrace could fail. Similarly for the other enums and + their values. */ +union +{ + enum CHECK_LISP_OBJECT_TYPE CHECK_LISP_OBJECT_TYPE; + enum enum_USE_LSB_TAG enum_USE_LSB_TAG; + enum Lisp_Bits Lisp_Bits; + enum More_Lisp_Bits More_Lisp_Bits; + enum pvec_type pvec_type; +} const EXTERNALLY_VISIBLE gdb_make_enums_visible = {0}; + +/* These symbols cannot be done as enums, since values might not be + in 'int' range. Each symbol X has a corresponding X_VAL symbol, + verified to have the correct value. */ #define ARRAY_MARK_FLAG_VAL PTRDIFF_MIN #define PSEUDOVECTOR_FLAG_VAL (PTRDIFF_MAX - PTRDIFF_MAX / 2) diff --git a/src/lisp.h b/src/lisp.h index c217b946e81..dd03a130c7c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -64,12 +64,6 @@ typedef unsigned int EMACS_UINT; # endif #endif -/* If an enum type is not used, the enum symbols are not put into the - executable so the debugger cannot see them on many systems, e.g., - GCC 4.7.1 + GDB 7.4.1 + GNU/Linux. Work around this problem by - explicitly using the names in the integer constant expression EXPR. */ -#define PUBLISH_TO_GDB(expr) extern int (*gdb_dummy (int))[(expr) || 1] - /* Number of bits in some machine integer types. */ enum { @@ -161,14 +155,23 @@ extern int suppress_checking EXTERNALLY_VISIBLE; variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ -/* Number of bits in a Lisp_Object tag. This can be used in #if, - and for GDB's sake also as a regular symbol. */ -enum { GCTYPEBITS = 3 }; -PUBLISH_TO_GDB (GCTYPEBITS); +enum Lisp_Bits + { + /* Number of bits in a Lisp_Object tag. This can be used in #if, + and for GDB's sake also as a regular symbol. */ + GCTYPEBITS = #define GCTYPEBITS 3 + GCTYPEBITS, + + /* Number of bits in a Lisp_Object value, not counting the tag. */ + VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, -/* Number of bits in a Lisp_Object value, not counting the tag. */ -enum { VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS }; + /* Number of bits in a Lisp fixnum tag. */ + INTTYPEBITS = GCTYPEBITS - 1, + + /* Number of bits in a Lisp fixnum value, not counting the tag. */ + FIXNUM_BITS = VALBITS + 1 + }; /* The maximum value that can be stored in a EMACS_INT, assuming all bits other than the type bits contribute to a nonnegative signed value. @@ -211,16 +214,12 @@ enum { VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS }; # endif # endif #endif -/* USE_LSB_TAG can be used in #if; default it to 0 and make it visible - to GDB. */ #ifdef USE_LSB_TAG # undef USE_LSB_TAG -enum { USE_LSB_TAG = 1 }; -PUBLISH_TO_GDB (USE_LSB_TAG); +enum enum_USE_LSB_TAG { USE_LSB_TAG = 1 }; # define USE_LSB_TAG 1 #else -enum { USE_LSB_TAG = 0 }; -PUBLISH_TO_GDB (USE_LSB_TAG); +enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; # define USE_LSB_TAG 0 #endif @@ -239,8 +238,6 @@ PUBLISH_TO_GDB (USE_LSB_TAG); /* Lisp integers use 2 tags, to give them one extra bit, thus extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ -enum { INTTYPEBITS = GCTYPEBITS - 1 }; -enum { FIXNUM_BITS = VALBITS + 1 }; #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) #define LISP_INT_TAG Lisp_Int0 #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 @@ -335,9 +332,9 @@ LISP_MAKE_RVALUE (Lisp_Object o) } #define LISP_INITIALLY_ZERO {0} -#undef CHECK_LISP_OBJECT_TYPE -enum { CHECK_LISP_OBJECT_TYPE = 1 }; +#undef CHECK_LISP_OBJECT_TYPE +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 }; #else /* CHECK_LISP_OBJECT_TYPE */ /* If a struct type is not wanted, define Lisp_Object as just a number. */ @@ -347,9 +344,8 @@ typedef EMACS_INT Lisp_Object; #define XIL(i) (i) #define LISP_MAKE_RVALUE(o) (0+(o)) #define LISP_INITIALLY_ZERO 0 -enum { CHECK_LISP_OBJECT_TYPE = 0 }; +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; #endif /* CHECK_LISP_OBJECT_TYPE */ -PUBLISH_TO_GDB (CHECK_LISP_OBJECT_TYPE); /* In the size word of a vector, this bit means the vector has been marked. */ @@ -390,35 +386,32 @@ enum pvec_type PVEC_SUB_CHAR_TABLE = 0x30, PVEC_FONT = 0x40 }; -PUBLISH_TO_GDB ((enum pvec_type) 0); /* This also publishes PVEC_*. */ -/* For convenience, we also store the number of elements in these bits. - Note that this size is not necessarily the memory-footprint size, but - only the number of Lisp_Object fields (that need to be traced by the GC). - The distinction is used e.g. by Lisp_Process which places extra - non-Lisp_Object fields at the end of the structure. */ -enum +/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers + which were stored in a Lisp_Object. */ +#ifndef DATA_SEG_BITS +# define DATA_SEG_BITS 0 +#endif +enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; +#undef DATA_SEG_BITS + +enum More_Lisp_Bits { + DATA_SEG_BITS = gdb_DATA_SEG_BITS, + + /* For convenience, we also store the number of elements in these bits. + Note that this size is not necessarily the memory-footprint size, but + only the number of Lisp_Object fields (that need to be traced by GC). + The distinction is used, e.g., by Lisp_Process, which places extra + non-Lisp_Object fields at the end of the structure. */ PSEUDOVECTOR_SIZE_BITS = 16, PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, - PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS - }; - -/* Number of bits to put in each character in the internal representation - of bool vectors. This should not vary across implementations. */ -enum { BOOL_VECTOR_BITS_PER_CHAR = 8 }; + PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS, -/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object. It is not needed in #if, so - for GDB's sake change it from a macro to a regular symbol. */ -#ifdef DATA_SEG_BITS -enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; -# undef DATA_SEG_BITS -enum { DATA_SEG_BITS = gdb_DATA_SEG_BITS }; -#else -enum { DATA_SEG_BITS = 0 }; -#endif -PUBLISH_TO_GDB (DATA_SEG_BITS); + /* Number of bits to put in each character in the internal representation + of bool vectors. This should not vary across implementations. */ + BOOL_VECTOR_BITS_PER_CHAR = 8 + }; /* These macros extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons,