Skip to content

Instantly share code, notes, and snippets.

@quarnster
Created February 1, 2014 10:41
Show Gist options
  • Save quarnster/8750586 to your computer and use it in GitHub Desktop.
Save quarnster/8750586 to your computer and use it in GitHub Desktop.
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <signal.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <setjmp.h>
void evil_c_recover() {
printf("%s\n", __PRETTY_FUNCTION__);
}
jmp_buf *evil_sig_jmp;
void evil_c_sig_handler(int sig) {
printf("%s: %d (%s)\n", __PRETTY_FUNCTION__, sig, strsignal(sig));
if (sig == SIGBUS || sig == SIGSEGV || sig == SIGFPE) {
if (evil_sig_jmp)
siglongjmp(*evil_sig_jmp, 1);
abort();
}
}
int q;
void* threadfunc(void* a) {
while (1) {
struct timespec timeout = { 5, 0 };
struct kevent e;
int status = kevent(q, NULL, 0, &e, 1, &timeout);
if (status == 0) {
printf("tick\n");
} else if (status > 0) {
printf("kevent: %d (%s): %d\n", (int) e.ident, strsignal((int) e.ident), (int) e.data);
if (e.ident == SIGINT) {
return NULL;
}
} else {
fprintf(stderr, "cound not kevent. Error is %d/%s\n", errno, strerror(errno));
return NULL;
}
}
return NULL;
}
int main(int argc, char **argv) {
q = kqueue();
pthread_t loop;
assert(q != -1);
struct kevent e;
EV_SET(&e, SIGBUS, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
assert(kevent(q, &e, 1, NULL, 0, NULL) != -1);
EV_SET(&e, SIGSEGV, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
assert(kevent(q, &e, 1, NULL, 0, NULL) != -1);
EV_SET(&e, SIGFPE, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
assert(kevent(q, &e, 1, NULL, 0, NULL) != -1);
EV_SET(&e, SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
assert(kevent(q, &e, 1, NULL, 0, NULL) != -1);
EV_SET(&e, SIGALRM, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL);
assert(kevent(q, &e, 1, NULL, 0, NULL) != -1);
signal(SIGBUS, evil_c_sig_handler);
signal(SIGSEGV, evil_c_sig_handler);
signal(SIGFPE, evil_c_sig_handler);
signal(SIGINT, evil_c_sig_handler);
signal(SIGALRM, evil_c_sig_handler);
pthread_create(&loop, NULL, threadfunc, NULL);
jmp_buf evil_c;
evil_sig_jmp = &evil_c;
if (sigsetjmp(evil_c, 1) == 0) {
int a = 100;
int b = 0;
printf("%d/%d = %d\n", a, b, a/b);
} else {
printf("nope\n");
}
if (sigsetjmp(evil_c, 1) == 0) {
int *a = 0;
printf("%d\n", *a);
} else {
printf("nope\n");
}
alarm(1);
pthread_join(loop, NULL);
close(q);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment