1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-12-01 02:37:39 +01:00
libunwind-eh_elf/tests/Ltest-init-local-signal.c
Yichao Yu 26c99a3a3e Fix init-local-signal test (#50)
* Add `SA_SIGINFO` flag

  This is needed to guarantee the availability of the `ucontext` argument

* Mark the `NULL` pointer load as `volatile`

  Further prevent any compiler optimization on the load.
2017-10-31 08:41:51 -07:00

60 lines
1.3 KiB
C

#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
* correctly (see impl of unw_init_local2) */
void handler(int num, siginfo_t* info, void* ucontext) {
unw_cursor_t c;
unw_context_t context;
unw_getcontext(&context);
int ret = unw_init_local2(&c, ucontext, UNW_INIT_SIGNAL_FRAME);
assert(!ret);
int ucontext_steps = stepper(&c);
ret = unw_init_local(&c, &context);
(void)ret;
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);
int main(){
struct sigaction a;
memset(&a, 0, sizeof(struct sigaction));
a.sa_sigaction = &handler;
a.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &a, NULL);
foo(NULL);
return 0;
}