Fix alignment-related core dump during GC.

* configure.in (GC_LISP_OBJECT_ALIGNMENT): Remove.
This is now done by src/alloc.c.
* src/alloc.c (GC_LISP_OBJECT_ALIGNMENT): Use offsetof, not __alignof__
or sizeof.  __alignof__ gives the wrong answer on Fedora x86-64
with GCC 4.6.1 when configured with CC='gcc -m32' --with-wide-int;
this makes Emacs dump core during garbage collection on rare
occasions.  sizeof is obviously inferior to offsetof here, so
stick with offsetof.
(GC_POINTER_ALIGNMENT): New macro.
(mark_memory): Omit 3rd (offset) arg; caller changed.
Don't assume EMACS_INT alignment is the same as pointer alignment.
This commit is contained in:
Paul Eggert 2011-10-07 00:23:44 -07:00
parent 21ce824514
commit 7c5ee88ecb
4 changed files with 34 additions and 23 deletions

View file

@ -1,3 +1,8 @@
2011-10-07 Paul Eggert <eggert@cs.ucla.edu>
* configure.in (GC_LISP_OBJECT_ALIGNMENT): Remove.
This is now done by src/alloc.c.
2011-10-02 Richard Stallman <rms@gnu.org>
* configure.in: Rename xlinux_first_failure to xgnu_linux_first_failure

View file

@ -3663,9 +3663,6 @@ AH_BOTTOM([
/* GC_SETJMP_WORKS is nearly always appropriate for GCC. */
# define GC_SETJMP_WORKS 1
# endif
# ifndef GC_LISP_OBJECT_ALIGNMENT
# define GC_LISP_OBJECT_ALIGNMENT (__alignof__ (Lisp_Object))
# endif
#endif
#endif /* EMACS_CONFIG_H */

View file

@ -1,3 +1,15 @@
2011-10-07 Paul Eggert <eggert@cs.ucla.edu>
* alloc.c (GC_LISP_OBJECT_ALIGNMENT): Use offsetof, not __alignof__
or sizeof. __alignof__ gives the wrong answer on Fedora x86-64
with GCC 4.6.1 when configured with CC='gcc -m32' --with-wide-int;
this makes Emacs dump core during garbage collection on rare
occasions. sizeof is obviously inferior to offsetof here, so
stick with offsetof.
(GC_POINTER_ALIGNMENT): New macro.
(mark_memory): Omit 3rd (offset) arg; caller changed.
Don't assume EMACS_INT alignment is the same as pointer alignment.
2011-10-03 Stefan Monnier <monnier@iro.umontreal.ca>
* keyboard.c (read_key_sequence_remapped): New var.

View file

@ -393,7 +393,7 @@ static int live_symbol_p (struct mem_node *, void *);
static int live_float_p (struct mem_node *, void *);
static int live_misc_p (struct mem_node *, void *);
static void mark_maybe_object (Lisp_Object);
static void mark_memory (void *, void *, int);
static void mark_memory (void *, void *);
static void mem_init (void);
static struct mem_node *mem_insert (void *, void *, enum mem_type);
static void mem_insert_fixup (struct mem_node *);
@ -4235,14 +4235,20 @@ mark_maybe_pointer (void *p)
}
#ifndef GC_LISP_OBJECT_ALIGNMENT
# define GC_LISP_OBJECT_ALIGNMENT offsetof (struct {char a; Lisp_Object b;}, b)
#endif
#define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b)
/* Mark Lisp objects referenced from the address range START+OFFSET..END
or END+OFFSET..START. */
static void
mark_memory (void *start, void *end, int offset)
mark_memory (void *start, void *end)
{
Lisp_Object *p;
void **pp;
int i;
#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
nzombies = 0;
@ -4258,8 +4264,9 @@ mark_memory (void *start, void *end, int offset)
}
/* Mark Lisp_Objects. */
for (p = (Lisp_Object *) ((char *) start + offset); (void *) p < end; ++p)
mark_maybe_object (*p);
for (p = start; (void *) p < end; p++)
for (i = 0; i < sizeof *p; i += GC_LISP_OBJECT_ALIGNMENT)
mark_maybe_object (*(Lisp_Object *) ((char *) p + i));
/* Mark Lisp data pointed to. This is necessary because, in some
situations, the C compiler optimizes Lisp objects away, so that
@ -4279,8 +4286,9 @@ mark_memory (void *start, void *end, int offset)
away. The only reference to the life string is through the
pointer `s'. */
for (pp = (void **) ((char *) start + offset); (void *) pp < end; ++pp)
mark_maybe_pointer (*pp);
for (pp = start; (void *) pp < end; pp++)
for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
mark_maybe_pointer (*(void **) ((char *) pp + i));
}
/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in
@ -4454,15 +4462,11 @@ dump_zombies (void)
pass starting at the start of the stack + 2. Likewise, if the
minimal alignment of Lisp_Objects on the stack is 1, four passes
would be necessary, each one starting with one byte more offset
from the stack start.
The current code assumes by default that Lisp_Objects are aligned
equally on the stack. */
from the stack start. */
static void
mark_stack (void)
{
int i;
void *end;
#ifdef HAVE___BUILTIN_UNWIND_INIT
@ -4520,15 +4524,8 @@ mark_stack (void)
/* This assumes that the stack is a contiguous region in memory. If
that's not the case, something has to be done here to iterate
over the stack segments. */
#ifndef GC_LISP_OBJECT_ALIGNMENT
#ifdef __GNUC__
#define GC_LISP_OBJECT_ALIGNMENT __alignof__ (Lisp_Object)
#else
#define GC_LISP_OBJECT_ALIGNMENT sizeof (Lisp_Object)
#endif
#endif
for (i = 0; i < sizeof (Lisp_Object); i += GC_LISP_OBJECT_ALIGNMENT)
mark_memory (stack_base, end, i);
mark_memory (stack_base, end);
/* Allow for marking a secondary stack, like the register stack on the
ia64. */
#ifdef GC_MARK_SECONDARY_STACK