Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Catching SIGSEGV (Segmentation Faults) in C
// This code installs a custom signal handler for the SIGSEGV signal
// (segmentation fault) and then purposefully creates a segmentation
// fault. The custom handler `handler` is then entered, which now
// increases the instruction pointer by 1, skipping the current byte
// of the faulty instruction. This is done for as long as the faulty
// instruction is still active; in the below case, that's 2 bytes.
// Note: This is for 64 bit systems. If you prefer 32 bit, change
// `REG_RIP` to `REG_EIP`. I didn't bother putting an appropriate
// `#ifdef` here.
#include <iostream>
#include <string.h>
#include <signal.h>
void handler(int nSignum, siginfo_t* si, void* vcontext) {
std::cout << "Segmentation fault" << std::endl;
ucontext_t* context = (ucontext_t*)vcontext;
context->uc_mcontext.gregs[REG_RIP]++;
}
int main() {
std::cout << "Start" << std::endl;
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = handler;
sigaction(SIGSEGV, &action, NULL);
int* x = 0;
int y = *x;
std::cout << "End" << std::endl;
return 0;
}
@fairlight1337

This comment has been minimized.

Copy link
Owner Author

@fairlight1337 fairlight1337 commented Apr 23, 2016

I did this as a cpp file (and use the std::cout machinery) because I like it that way. The relevant SIGSEGV catching code is pure C, though.

string.h is only in there for memset.

The segfault happens when entering line 37,

int y = *x;

because then the value referenced by int* x (which is 0) is dereferenced.

@varun1729

This comment has been minimized.

Copy link

@varun1729 varun1729 commented Feb 10, 2019

Do not use cout as it is not signal or thread safe use POSIX compliant write(2), which is unbuffered unlike cout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment