mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 16:36:21 +00:00
73 lines
1.6 KiB
C
73 lines
1.6 KiB
C
/* Test of correct simulation for active stack. */
|
|
|
|
#include <assert.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <ucontext.h>
|
|
|
|
static char altstack_map[8096];
|
|
static volatile stack_t *sp;
|
|
|
|
static void sighandler(int sig)
|
|
{
|
|
/* Check that the alternate stack is active. */
|
|
assert(sp->ss_sp == altstack_map);
|
|
assert(sp->ss_size == sizeof(altstack_map));
|
|
assert(sp->ss_flags == SS_ONSTACK);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
stack_t mainstack;
|
|
stack_t altstack;
|
|
struct sigaction sa;
|
|
/* Obtain an address inside the stack using a dirty trick. */
|
|
void *local = &sa;
|
|
|
|
/* Get an address for stack definition. */
|
|
if (getustack((stack_t**)&sp)) {
|
|
perror("getustack");
|
|
return 1;
|
|
}
|
|
|
|
/* Check the current stack. */
|
|
assert(sp->ss_sp <= local);
|
|
assert(local < (void*)((char*)sp->ss_sp + sp->ss_size));
|
|
assert(sp->ss_flags == 0);
|
|
|
|
/* Backup the current stack. */
|
|
mainstack = *sp;
|
|
|
|
/* Setup a signal handler. */
|
|
sa.sa_handler = sighandler;
|
|
sa.sa_flags = SA_ONSTACK;
|
|
if (sigfillset(&sa.sa_mask)) {
|
|
perror("sigfillset");
|
|
return 1;
|
|
}
|
|
if (sigaction(SIGUSR1, &sa, NULL)) {
|
|
perror("sigaction");
|
|
return 1;
|
|
}
|
|
|
|
/* Setup an alternate stack. */
|
|
altstack.ss_sp = altstack_map;
|
|
altstack.ss_size = sizeof(altstack_map);
|
|
altstack.ss_flags = 0;
|
|
if (sigaltstack(&altstack, NULL)) {
|
|
perror("sigaltstack");
|
|
return 1;
|
|
}
|
|
|
|
/* Raise a signal. */
|
|
raise(SIGUSR1);
|
|
|
|
/* Check the current stack. */
|
|
assert(mainstack.ss_sp == sp->ss_sp);
|
|
assert(mainstack.ss_size == sp->ss_size);
|
|
assert(mainstack.ss_flags == sp->ss_flags);
|
|
|
|
return 0;
|
|
}
|
|
|