/*WBL 11 Nov 2020 */ /*Modifications: WBL 13 Nov 2020 Fix for stack overflow SIGSEGV too WBL 11 Nov 2020 Try Dan Blackwell's SIGSEGV handler. Cf: https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes */ /*compile with -g and link with -rdynamic. Eg: gcc -g -rdynamic segv.c */ /*run (various) eg: ./a.out gdb -batch -ex=run -ex=bt ./a.out */ #include #include #include #include #include #include /*Alternative stack so can hangle stack overflow*/ /*https://www.gnu.org/software/libc/manual/html_node/Signal-Stack.html */ /*https://stackoverflow.com/questions/5785746/how-to-use-sigaltstack-in-signal-handler-program*/ /*https://www.gnu.org/software/libc/manual/html_node/Backtraces.html*/ void handler(int sig) { const int bt_size = 20; void *array[bt_size]; size_t size; /*use write as stream IO fails when stack is trashed*/ char buf[80]; sprintf(buf,"signal handler(%d)\n",sig); write(STDERR_FILENO,buf,strlen(buf)); /* get void*'s for all entries on the stack * NB backtrace may sometimes return 0, * eg in cluster when all memory is used up */ size = backtrace(array, bt_size); sprintf(buf,"backtrace(array,%d) gives %d pointers\n",bt_size,size); write(STDERR_FILENO,buf,strlen(buf)); // print out all the frames to stderr //fprintf(stderr, "Error: signal %d:\n", sig); backtrace_symbols_fd(array, size, STDERR_FILENO); exit(128+sig); } void A(); void C(const int c, const char* text) { printf("C(%d,%s) called\n",c,text); //A(); //recurse until exhaust stack int* bad = 0; bad[1] = 999; } void B(const int b) { printf("B(%d) called\n",b); C(b,"c"); } void A() { printf("A called\n"); B(1); } char stack[SIGSTKSZ]; stack_t signal_stack_info = { .ss_size = SIGSTKSZ, .ss_sp = stack, }; struct sigaction signal_action_info = { .sa_handler = handler, .sa_flags = SA_ONSTACK }; int main(int argc, char * argv[]){ int i; printf("$Revision: 1.4 $\n"); for(i=0; i