#include "backtrace.h" /* fix VC++ ugliness */ #ifdef WIN32 # define snprintf _snprintf #endif /* make_backtrace() produces a backtrace for the current thread, and puts it * in the buffer 'backtrace_text', up to 'size' characters. */ int make_backtrace(char *backtrace_text, size_t size) { #ifndef HAS_EXECINFO /* if we haven't got execinfo.h, simply make this return failure string */ #ifdef WIN32 sprintf(backtrace_text, "%.100s:%d: Windows backtrace info\n", __FILE__, __LINE__); #else sprintf(backtrace_text, "%.100s:%d: execinfo.h not included, so no backtrace produced\n", __FILE__, __LINE__); #endif return 0; #else char temp_buffer[BACKTRACE_BFSZ]; /* buffer to hold one line of backtrace */ char **backtrace_strings; /* string table containing whole backtrace */ int backtrace_size; /* number of elements in backtrace */ int i; /* current position within backtrace */ void *backtrace_buffer[BACKTRACE_BFSZ]; /* buffer to hold elements of backtrace */ /* get backtrace elements */ backtrace_size = backtrace(backtrace_buffer, BACKTRACE_BFSZ); /* fail if none are returned */ if ( ! backtrace_size ) { snprintf(backtrace_text, size - 1, "%s:%d: backtrace() failed, so no backtrace produced\n", __FILE__, __LINE__); return 0; } /* add symbolic information in backtrace to make it useful, and store in string table */ backtrace_strings = backtrace_symbols(backtrace_buffer, backtrace_size); /* check we actually got some strings */ if ( ! backtrace_strings ) { snprintf(backtrace_text, size - 1, "%s:%d: insufficient memory for backtrace_symbols()\n", __FILE__, __LINE__); return 0; } /* store entire backtrace in backtrace_text */ *backtrace_text = '\0'; for ( i = 0; i < backtrace_size; i ++ ) { snprintf(temp_buffer, BACKTRACE_BFSZ - 1, "%s\n", backtrace_strings[i]); strncat(backtrace_text, temp_buffer, size - 1); } /* if we get here, then clean up and return success */ free(backtrace_strings); return 1; #endif } /* The main() and foobar() functions are only included for testing - they are * enabled by "#define BACKTRACE_TESTING" in trace.h. */ #ifdef BACKTRACE_TESTING void foobar(int baz) { char buffer[1024]; // printf("%d\n", baz); make_backtrace(buffer, 1024); // printf("%s", buffer); } int main(void) { foobar(9); return EXIT_SUCCESS; } #endif