• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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