diff options
| author | Paul Eggert | 2011-10-07 00:23:44 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-10-07 00:23:44 -0700 |
| commit | 7c5ee88ecb336a2deac1c1b98753f08ef0a2bd1c (patch) | |
| tree | 10a208e0778b6ca9d376b8c879ff23b28deb1d30 /src | |
| parent | 21ce8245145810da59c854a172900894f22c175c (diff) | |
| download | emacs-7c5ee88ecb336a2deac1c1b98753f08ef0a2bd1c.tar.gz emacs-7c5ee88ecb336a2deac1c1b98753f08ef0a2bd1c.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/alloc.c | 37 |
2 files changed, 29 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b697ee43376..d2c069b7351 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2011-10-07 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * alloc.c (GC_LISP_OBJECT_ALIGNMENT): Use offsetof, not __alignof__ | ||
| 4 | or sizeof. __alignof__ gives the wrong answer on Fedora x86-64 | ||
| 5 | with GCC 4.6.1 when configured with CC='gcc -m32' --with-wide-int; | ||
| 6 | this makes Emacs dump core during garbage collection on rare | ||
| 7 | occasions. sizeof is obviously inferior to offsetof here, so | ||
| 8 | stick with offsetof. | ||
| 9 | (GC_POINTER_ALIGNMENT): New macro. | ||
| 10 | (mark_memory): Omit 3rd (offset) arg; caller changed. | ||
| 11 | Don't assume EMACS_INT alignment is the same as pointer alignment. | ||
| 12 | |||
| 1 | 2011-10-03 Stefan Monnier <monnier@iro.umontreal.ca> | 13 | 2011-10-03 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 14 | ||
| 3 | * keyboard.c (read_key_sequence_remapped): New var. | 15 | * keyboard.c (read_key_sequence_remapped): New var. |
diff --git a/src/alloc.c b/src/alloc.c index ead5c8a8ca4..f4db3abbd93 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -393,7 +393,7 @@ static int live_symbol_p (struct mem_node *, void *); | |||
| 393 | static int live_float_p (struct mem_node *, void *); | 393 | static int live_float_p (struct mem_node *, void *); |
| 394 | static int live_misc_p (struct mem_node *, void *); | 394 | static int live_misc_p (struct mem_node *, void *); |
| 395 | static void mark_maybe_object (Lisp_Object); | 395 | static void mark_maybe_object (Lisp_Object); |
| 396 | static void mark_memory (void *, void *, int); | 396 | static void mark_memory (void *, void *); |
| 397 | static void mem_init (void); | 397 | static void mem_init (void); |
| 398 | static struct mem_node *mem_insert (void *, void *, enum mem_type); | 398 | static struct mem_node *mem_insert (void *, void *, enum mem_type); |
| 399 | static void mem_insert_fixup (struct mem_node *); | 399 | static void mem_insert_fixup (struct mem_node *); |
| @@ -4235,14 +4235,20 @@ mark_maybe_pointer (void *p) | |||
| 4235 | } | 4235 | } |
| 4236 | 4236 | ||
| 4237 | 4237 | ||
| 4238 | #ifndef GC_LISP_OBJECT_ALIGNMENT | ||
| 4239 | # define GC_LISP_OBJECT_ALIGNMENT offsetof (struct {char a; Lisp_Object b;}, b) | ||
| 4240 | #endif | ||
| 4241 | #define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b) | ||
| 4242 | |||
| 4238 | /* Mark Lisp objects referenced from the address range START+OFFSET..END | 4243 | /* Mark Lisp objects referenced from the address range START+OFFSET..END |
| 4239 | or END+OFFSET..START. */ | 4244 | or END+OFFSET..START. */ |
| 4240 | 4245 | ||
| 4241 | static void | 4246 | static void |
| 4242 | mark_memory (void *start, void *end, int offset) | 4247 | mark_memory (void *start, void *end) |
| 4243 | { | 4248 | { |
| 4244 | Lisp_Object *p; | 4249 | Lisp_Object *p; |
| 4245 | void **pp; | 4250 | void **pp; |
| 4251 | int i; | ||
| 4246 | 4252 | ||
| 4247 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 4253 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| 4248 | nzombies = 0; | 4254 | nzombies = 0; |
| @@ -4258,8 +4264,9 @@ mark_memory (void *start, void *end, int offset) | |||
| 4258 | } | 4264 | } |
| 4259 | 4265 | ||
| 4260 | /* Mark Lisp_Objects. */ | 4266 | /* Mark Lisp_Objects. */ |
| 4261 | for (p = (Lisp_Object *) ((char *) start + offset); (void *) p < end; ++p) | 4267 | for (p = start; (void *) p < end; p++) |
| 4262 | mark_maybe_object (*p); | 4268 | for (i = 0; i < sizeof *p; i += GC_LISP_OBJECT_ALIGNMENT) |
| 4269 | mark_maybe_object (*(Lisp_Object *) ((char *) p + i)); | ||
| 4263 | 4270 | ||
| 4264 | /* Mark Lisp data pointed to. This is necessary because, in some | 4271 | /* Mark Lisp data pointed to. This is necessary because, in some |
| 4265 | situations, the C compiler optimizes Lisp objects away, so that | 4272 | situations, the C compiler optimizes Lisp objects away, so that |
| @@ -4279,8 +4286,9 @@ mark_memory (void *start, void *end, int offset) | |||
| 4279 | away. The only reference to the life string is through the | 4286 | away. The only reference to the life string is through the |
| 4280 | pointer `s'. */ | 4287 | pointer `s'. */ |
| 4281 | 4288 | ||
| 4282 | for (pp = (void **) ((char *) start + offset); (void *) pp < end; ++pp) | 4289 | for (pp = start; (void *) pp < end; pp++) |
| 4283 | mark_maybe_pointer (*pp); | 4290 | for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) |
| 4291 | mark_maybe_pointer (*(void **) ((char *) pp + i)); | ||
| 4284 | } | 4292 | } |
| 4285 | 4293 | ||
| 4286 | /* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in | 4294 | /* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in |
| @@ -4454,15 +4462,11 @@ dump_zombies (void) | |||
| 4454 | pass starting at the start of the stack + 2. Likewise, if the | 4462 | pass starting at the start of the stack + 2. Likewise, if the |
| 4455 | minimal alignment of Lisp_Objects on the stack is 1, four passes | 4463 | minimal alignment of Lisp_Objects on the stack is 1, four passes |
| 4456 | would be necessary, each one starting with one byte more offset | 4464 | would be necessary, each one starting with one byte more offset |
| 4457 | from the stack start. | 4465 | from the stack start. */ |
| 4458 | |||
| 4459 | The current code assumes by default that Lisp_Objects are aligned | ||
| 4460 | equally on the stack. */ | ||
| 4461 | 4466 | ||
| 4462 | static void | 4467 | static void |
| 4463 | mark_stack (void) | 4468 | mark_stack (void) |
| 4464 | { | 4469 | { |
| 4465 | int i; | ||
| 4466 | void *end; | 4470 | void *end; |
| 4467 | 4471 | ||
| 4468 | #ifdef HAVE___BUILTIN_UNWIND_INIT | 4472 | #ifdef HAVE___BUILTIN_UNWIND_INIT |
| @@ -4520,15 +4524,8 @@ mark_stack (void) | |||
| 4520 | /* This assumes that the stack is a contiguous region in memory. If | 4524 | /* This assumes that the stack is a contiguous region in memory. If |
| 4521 | that's not the case, something has to be done here to iterate | 4525 | that's not the case, something has to be done here to iterate |
| 4522 | over the stack segments. */ | 4526 | over the stack segments. */ |
| 4523 | #ifndef GC_LISP_OBJECT_ALIGNMENT | 4527 | mark_memory (stack_base, end); |
| 4524 | #ifdef __GNUC__ | 4528 | |
| 4525 | #define GC_LISP_OBJECT_ALIGNMENT __alignof__ (Lisp_Object) | ||
| 4526 | #else | ||
| 4527 | #define GC_LISP_OBJECT_ALIGNMENT sizeof (Lisp_Object) | ||
| 4528 | #endif | ||
| 4529 | #endif | ||
| 4530 | for (i = 0; i < sizeof (Lisp_Object); i += GC_LISP_OBJECT_ALIGNMENT) | ||
| 4531 | mark_memory (stack_base, end, i); | ||
| 4532 | /* Allow for marking a secondary stack, like the register stack on the | 4529 | /* Allow for marking a secondary stack, like the register stack on the |
| 4533 | ia64. */ | 4530 | ia64. */ |
| 4534 | #ifdef GC_MARK_SECONDARY_STACK | 4531 | #ifdef GC_MARK_SECONDARY_STACK |