1 #include "libunwind.h"
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <string.h>
5
6 #include <stdlib.h>
7
8 #include <signal.h>
9 #include <stdio.h>
10 #include <assert.h>
11
stepper(unw_cursor_t * c)12 int stepper(unw_cursor_t* c) {
13 int steps = 0;
14 int ret = 1;
15 while (ret) {
16
17 ret = unw_step(c);
18 if (!ret) {
19 break;
20 }
21 steps++;
22 }
23 return steps;
24 }
25
26 /* Verify that we can step from both ucontext, and from getcontext()
27 * roughly the same. This tests that the IP from ucontext is used
28 * correctly (see impl of unw_init_local2) */
handler(int num,siginfo_t * info,void * ucontext)29 void handler(int num, siginfo_t* info, void* ucontext) {
30 unw_cursor_t c;
31 unw_context_t context;
32 unw_getcontext(&context);
33 int ret = unw_init_local2(&c, ucontext, UNW_INIT_SIGNAL_FRAME);
34 assert(!ret);
35 int ucontext_steps = stepper(&c);
36
37 ret = unw_init_local(&c, &context);
38 (void)ret;
39 assert(!ret);
40 int getcontext_steps = stepper(&c);
41 if (ucontext_steps == getcontext_steps - 2) {
42 exit(0);
43 }
44 printf("unw_getcontext steps was %i, ucontext steps was %i, should be %i\n",
45 getcontext_steps, ucontext_steps, getcontext_steps - 2);
46 exit(-1);
47 }
48
49 int foo(volatile int* f);
50
main()51 int main(){
52 struct sigaction a;
53 memset(&a, 0, sizeof(struct sigaction));
54 a.sa_sigaction = &handler;
55 a.sa_flags = SA_SIGINFO;
56 sigaction(SIGSEGV, &a, NULL);
57
58 foo(NULL);
59 return 0;
60 }
61