Skip to content

Instantly share code, notes, and snippets.

@landonf
Created June 17, 2011 22:51
Show Gist options
  • Save landonf/1032539 to your computer and use it in GitHub Desktop.
Save landonf/1032539 to your computer and use it in GitHub Desktop.
Explanation of why backtrace(3) and stack overflow don't mix.
#import <Foundation/Foundation.h>
#import <pthread.h>
#import <execinfo.h>
#import <string.h>
#import <stdint.h>
/*
* A signal handler that is broken in two ways:
* 1) The handler calls APIs that are not declared to be async-safe and may deadlock or otherwise fail.
* 2) The handler can not capture a backtrace should the stack overflow.
*/
static void unsafe_signal_handler (int signo) {
signal(signo, SIG_DFL);
/* Attempt to use backtrace(3) to fetch the backtrace. This requires that we be
* operating on the crashed thread's stack, but that stack just overflowed,
* and our signal handler will simply crash.
*
* However, if we used sigaltstack() to correctly run on a different stack, our
* backtrace would be empty! This is not limited to backtrace(3) -- [NSThread callStackReturnAddresses]
* will exhibit the same behavior.
*
* This is one reason why backtraces must be implemented by implementing your own stack walking
* using the ucontext_t from the SA_SIGINFO prototype.
*/
void *callstack[128];
int count = backtrace(callstack, 128);
backtrace_symbols_fd(callstack, count, STDERR_FILENO);
}
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
/* Set up the signal handler. */
signal(SIGABRT, unsafe_signal_handler);
signal(SIGSEGV, unsafe_signal_handler);
/* Run some buggy code in an unusual code path. A small typo will trigger infinite recursion ... */
NSArray *resultMessages = [NSMutableArray arrayWithObject: @"Error message!"];
NSMutableArray *results = [[NSMutableArray alloc] init];
for (NSObject *result in resultMessages)
[results addObject: results]; // Whoops!
NSLog(@"Some strange unexpected error we never see occured with results: %@", results);
[pool drain];
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment