Skip to content

Instantly share code, notes, and snippets.

Created September 4, 2011 07:29
Show Gist options
  • Save anonymous/1192449 to your computer and use it in GitHub Desktop.
Save anonymous/1192449 to your computer and use it in GitHub Desktop.
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
sigjmp_buf return_point;
/* 適切で無いハンドラ */
static void signal_handler(int sig, siginfo_t* sig_info, void* sig_data) {
puts("catch SIGSEGV & return");
siglongjmp(return_point,1);
return;
}
struct Stack {
uint32_t used;
int *array;
};
void destruct(struct Stack s)
{
free(s.array);
}
void print_stack(struct Stack s)
{
uint32_t i = s.used;
printf("stack length : %u\n",s.used);
printf("Top :");
for(; i != 0; --i) {
printf(" %u ",s.array[i-1]);
}
puts("");
}
void DERUARU(struct Stack *s)
{
s->used = 0;
s->array = NULL;
}
void move(int *dst,struct Stack * const s)
{
memcpy(dst,s->array,sizeof(int) * s->used);
free(s->array);
s->array = NULL;
}
void push(int v,struct Stack * const s,
void (*S)(struct Stack),
void (*F)(void))
{
int *tmp = malloc(sizeof(int) * (s->used + 1));
if(tmp == NULL)
F();
move(tmp,s);
tmp[s->used] = v;
++s->used;
s->array = tmp;
S(*s);
}
void top(struct Stack s,
void (*S)(int),
void (*F)(void))
{
if(s.used == 0)
F();
else
S(s.array[s.used - 1]);
}
void pop(struct Stack *s,
void (*S)(int),
void (*F1)(void),
void (*F2)(void))
{
if(s->used == 0)
F1();
else
{
void cont(int v)
{
int *tmp = malloc(sizeof(int) * (s->used - 1));
if(tmp == NULL)
F2();
--s->used;
move(tmp,s);
s->array = tmp;
S(v);
}
top(*s,cont,NULL);
}
}
void pushloop(int i,struct Stack *sp)
{
double nouse[60000];
void success(struct Stack s)
{
print_stack(*sp);
if(sigsetjmp(return_point , 1) == 0)
pushloop(i+1,sp);
else
destruct(*sp);
}
void fail(void)
{
destruct(*sp);
}
push(i,sp,success,fail);
}
int main()
{
struct Stack s;DERUARU(&s);
stack_t ss;
if((ss.ss_sp = malloc(4096 * 8)) == NULL) {
perror("separate signal stack allcation error");
exit(1);
}
ss.ss_size = 4096 * 8;
ss.ss_flags = 0;
if(sigaltstack(&ss,NULL)) {
perror("sigaltstack");
exit(1);
}
struct sigaction sa_segv;
memset(&sa_segv,0,sizeof(sa_segv));
sa_segv.sa_sigaction = signal_handler;
sa_segv.sa_flags = SA_SIGINFO | SA_ONSTACK;
if(sigaction(SIGSEGV,&sa_segv,NULL) < 0 ||
sigaction(SIGBUS ,&sa_segv,NULL) < 0)
{
perror("sigaction");
exit(1);
}
pushloop(0,&s);
free(ss.ss_sp);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment