Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Compile with gcc -Wall -pedantic-errors -std=gnu99 foo.c
- //
- #include <stdio.h>
- #include <setjmp.h>
- #include <signal.h>
- // Pointer to functions like void f(void)
- //
- typedef void (*Func)(void);
- // Store where to go when SIGSEGV caught
- //
- static sigjmp_buf jumpTarget;
- // Called when SIGSEGV caught
- //
- static void sigHandler(int sig) {
- siglongjmp(jumpTarget, sig);
- }
- // Execute the supplied function, return 0 for success and 1 for SIGSEGV
- //
- int catchCrash(Func f) {
- struct sigaction oldAction;
- struct sigaction newAction;
- // Remember the old SIGSEGV handler and set a new handler
- newAction.sa_flags = 0;
- newAction.sa_handler = sigHandler;
- sigemptyset(&newAction.sa_mask);
- sigaction(SIGSEGV, &newAction, &oldAction);
- // Crashing code ends up inside this block
- if ( __extension__ sigsetjmp(jumpTarget, 1) != 0 ) {
- return 1; // crash detected
- }
- // Execute the function: maybe crash, maybe not
- f();
- // Restore the old handler
- sigaction(SIGSEGV, &oldAction, NULL);
- return 0;
- }
- // Innocuous function
- //
- void sayHello(void) {
- printf("Hello World\n");
- }
- // Attempt to write to address zero
- //
- void writeZero(void) {
- int *p = NULL;
- *p = 42;
- }
- // Attempt to read from address zero
- //
- void readZero(void) {
- int *p = NULL;
- printf("Read: %d\n", *p);
- }
- // Attempt to execute code at address zero
- //
- void jmpZero(void) {
- Func f = NULL;
- f();
- }
- int main(void) {
- printf("catchCrash(sayHello) returned %d\n", catchCrash(sayHello));
- printf("catchCrash(writeZero) returned %d\n", catchCrash(writeZero));
- printf("catchCrash(readZero) returned %d\n", catchCrash(readZero));
- printf("catchCrash(jmpZero) returned %d\n", catchCrash(jmpZero));
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement