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