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