This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Weird startup issue with -fsplit-stack
- From: Dmitry Antipov <dmantipov at yandex dot ru>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 20 May 2014 18:18:43 +0400
- Subject: Weird startup issue with -fsplit-stack
- Authentication-results: sourceware.org; auth=none
- Authentication-results: smtp7.mail.yandex.net; dkim=pass header dot i= at yandex dot ru
Hello,
I'm trying to support -fsplit-stack in GNU Emacs. The most important problem is that
GC uses conservative scanning of a C stack, so I need to iterate over stack segments.
I'm doing this by using __splitstack_find, as described in libgcc/generic-morestack.c;
but now I'm facing the weird issue with startup:
Core was generated by `./temacs --batch --load loadup bootstrap'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:486
486 pushq %rax
(gdb) bt 10
#0 __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:486
#1 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#2 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#3 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#4 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#5 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#6 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#7 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#8 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#9 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
(More stack frames follow...)
(gdb) bt -10
#87310 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87311 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87312 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87313 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87314 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87315 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87316 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87317 0x00000000005f15df in __morestack () at ../../../gcc-4.9.0/libgcc/config/i386/morestack.S:502
#87318 0x0000003791a21d65 in __libc_start_main (main=0x4d111d <main>, argc=5, argv=0x7fffacc868d8, init=<optimized out>,
fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffacc868c8) at libc-start.c:285
#87319 0x0000000000405f69 in _start ()
(gdb)
Unfortunately I was unable to reproduce this issue with small test programs, so
there is no simple and easy-to-use recipe. Anyway, if someone would like to try:
bzr branch bzr://bzr.savannah.gnu.org/emacs/trunk
cd trunk
cat /path/to/emacs_split_stack.patch | patch -p0
# 'configure' options for 'smallest possible' configuration
CPPFLAGS='-DSPLIT_STACK=1' CFLAGS='-O0 -g3 -fsplit-stack' ./configure --prefix=/some/dir --without-all --without-x --disable-acl
make
I'm using (homebrew) GCC 4.9.0 and (stock) gold 2.24 on a Fedora 20 system.
Dmitry
=== modified file 'src/alloc.c'
--- src/alloc.c 2014-05-19 19:19:05 +0000
+++ src/alloc.c 2014-05-20 14:01:56 +0000
@@ -4932,11 +4932,28 @@
#endif /* not GC_SAVE_REGISTERS_ON_STACK */
#endif /* not HAVE___BUILTIN_UNWIND_INIT */
- /* 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. */
+#ifdef SPLIT_STACK
+
+ /* This assumes gcc >= 4.6.0 with -fsplit-stack
+ and corresponding support in libgcc. */
+ {
+ size_t stack_size;
+ extern void * __splitstack_find (void *, void *, size_t *,
+ void **, void **, void **);
+ void *next_segment = NULL, *next_sp = NULL, *initial_sp = NULL, *stack;
+
+ while ((stack = __splitstack_find (next_segment, next_sp, &stack_size,
+ &next_segment, &next_sp, &initial_sp)))
+ mark_memory (stack, (char *) stack + stack_size);
+ }
+
+#else /* not SPLIT_STACK */
+
+ /* This assumes that the stack is a contiguous region in memory. */
mark_memory (stack_base, end);
+#endif /* SPLIT_STACK */
+
/* Allow for marking a secondary stack, like the register stack on the
ia64. */
#ifdef GC_MARK_SECONDARY_STACK