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// Tests _Unwind_Backtrace() 12// 13 14#include <stdio.h> 15#include <stdlib.h> 16#include <string.h> 17#include <dlfcn.h> 18 19#include "unwind.h" 20 21 22// put intermediate function into another file so compiler does not optimze away 23extern int foo(); 24 25static const char* expected[] = { "bar", "foo", "main" }; 26 27static int step = 0; 28static _Unwind_Reason_Code handler(struct _Unwind_Context* context, void* ref) 29{ 30 if ( step > 2 ) 31 return _URC_NORMAL_STOP; 32 struct dl_info dyldInfo; 33 if ( dladdr((void*)_Unwind_GetIP(context), &dyldInfo) ) { 34 if ( strcmp(dyldInfo.dli_sname, expected[step]) != 0 ) { 35 fprintf(stderr, "unexpected frame %s\n", dyldInfo.dli_sname); 36 exit(1); 37 } 38 ++step; 39 } 40 else { 41 exit(1); 42 } 43 return _URC_NO_REASON; 44} 45 46 47 48int bar() 49{ 50 _Unwind_Backtrace(&handler, NULL); 51 return (step == 2); 52} 53 54 55int main() 56{ 57 return foo(); 58} 59 60