/*-------------------------------------------------------------------------- Demonstration of problem with -fcheck-stack in gcc Most of the complexity in this demo is to demonstrate that -fcheck-stack is working properly for user-created threads. The bug is only in the main thread. Workaround: be extremely sparing of stack space in the main thread if you want your program to work with -fcheck-stack. case 1: bug To reproduce, compile with -fcheck-stack and run under gdb. It will crash not where you expect it, but immediately on startup! You can remove everything but main(), foo, and exit, and it will still crash. case 2: normal Reduce the size of the 'foo' array in main to 2000 bytes, compile with -fcheck-stack, and run under gdb. A SIGSEGV will be generated on the first call to threadMain, as intended. case 3: normal With the size of the 'foo' array in main still 2000 bytes as in case 2, compile without -fcheck-stack, and run under gdb. A SIGSEGV will be generated on the second call to threadMain. This indicates that -fcheck-stack properly helps locate thread stack overruns early. --------------------------------------------------------------------------*/ #include #include #define MYSTACKSIZE (1<<18) /* A thread function that uses two pages more stack * than the stack size. Assuming this program uses * the default single guard page, this will not trigger * a SIGSEGV unless stack checks are turned on with * -fstack-check. * This works properly; -fstack-check catches the problem * sooner! */ void *threadMain(void *arg) { char foo[MYSTACKSIZE + 2*4096]; return threadMain(arg); } int main(int argc, char **argv) { /* Here's the rub: the main thread seems to only have a 4K stack! */ /* Increasing foo much past 2000 causes a segfault. */ char foo[4017]; int err; pthread_t thr; pthread_attr_t attrs; pthread_attr_init(&attrs); err = pthread_attr_setstacksize(&attrs, MYSTACKSIZE); assert(err == 0); err = pthread_create(&thr, &attrs, threadMain, 0); assert(err == 0); sleep(2); exit(0); }