1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-25 16:47:38 +01:00
libunwind-eh_elf/tests/Ltest-init-local-signal.c

61 lines
1.3 KiB
C
Raw Normal View History

2017-04-03 23:35:24 +02:00
#include "libunwind.h"
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <assert.h>
int stepper(unw_cursor_t* c) {
int steps = 0;
int ret = 1;
while (ret) {
ret = unw_step(c);
if (!ret) {
break;
}
steps++;
}
return steps;
}
/* Verify that we can step from both ucontext, and from getcontext()
* roughly the same. This tests that the IP from ucontext is used
2017-08-16 20:27:43 +02:00
* correctly (see impl of unw_init_local2) */
2017-04-03 23:35:24 +02:00
void handler(int num, siginfo_t* info, void* ucontext) {
unw_cursor_t c;
unw_context_t context;
unw_getcontext(&context);
2017-08-16 20:27:43 +02:00
int ret = unw_init_local2(&c, ucontext, UNW_INIT_SIGNAL_FRAME);
2017-04-03 23:35:24 +02:00
assert(!ret);
int ucontext_steps = stepper(&c);
ret = unw_init_local(&c, &context);
(void)ret;
2017-04-03 23:35:24 +02:00
assert(!ret);
int getcontext_steps = stepper(&c);
if (ucontext_steps == getcontext_steps - 2) {
exit(0);
}
printf("unw_getcontext steps was %i, ucontext steps was %i, should be %i\n",
getcontext_steps, ucontext_steps, getcontext_steps - 2);
exit(-1);
}
int foo(volatile int* f);
2017-04-03 23:35:24 +02:00
int main(){
struct sigaction a;
memset(&a, 0, sizeof(struct sigaction));
a.sa_sigaction = &handler;
a.sa_flags = SA_SIGINFO;
2017-04-03 23:35:24 +02:00
sigaction(SIGSEGV, &a, NULL);
foo(NULL);
return 0;
2017-04-03 23:35:24 +02:00
}