1 2// 3// TEST-OPTIONS: backtrace2.c -arch i386 -fexceptions 4// TEST-OPTIONS: backtrace2.c -arch i386 -fexceptions -fomit-frame-pointer 5// TEST-OPTIONS: backtrace2.c -arch i386 -fexceptions -Wl,-no_compact_unwind 6// TEST-OPTIONS: backtrace2.c -arch x86_64 7// TEST-OPTIONS: backtrace2.c -arch x86_64 -fomit-frame-pointer 8// TEST-OPTIONS: backtrace2.c -arch x86_64 -Wl,-no_compact_unwind 9// TEST-OPTIONS: backtrace2.c -arch ppc -fexceptions 10// 11// Basic backtrace test 12// 13 14#include <stdio.h> 15#include <stdlib.h> 16#include <string.h> 17#include <pthread.h> 18 19#include "libunwind.h" 20 21static const char* other_expected[] = { "bar", "foo", "work", "_pthread_start", NULL, NULL }; 22static const char* main_expected[] = { "bar", "foo", "main", NULL, NULL }; 23 24 25// put intermediate function into another file so compiler does not optimze away 26extern int foo(const char** list); 27 28 29int bar(const char** list) 30{ 31 char functionName[64]; 32 unw_cursor_t cursor; 33 unw_context_t uc; 34 unw_word_t offset; 35 36 int index = 0; 37 unw_getcontext(&uc); 38 unw_init_local(&cursor, &uc); 39 do { 40 unw_get_proc_name(&cursor, functionName, 64, &offset); 41 //fprintf(stderr, "in function: %s\n", functionName); 42 if ( (list[index] != NULL) && (strcmp(functionName, list[index]) != 0) ) { 43 //fprintf(stderr, "unexpected function: %s\n", functionName); 44 exit(1); 45 } 46 ++index; 47 } while (unw_step(&cursor) > 0); 48 return 0; 49} 50 51static void* work(void* arg) 52{ 53 foo((const char**)arg); 54 return NULL; 55} 56 57 58int main() 59{ 60 // test back traces on another thread 61 pthread_t worker1; 62 if ( pthread_create(&worker1, NULL, work, other_expected) != 0 ) { 63 exit(0); 64 } 65 void* result; 66 pthread_join(worker1, &result); 67 68 // test back traces on main thread 69 return foo(main_expected); 70} 71 72