diff --git a/src/Makefile b/src/Makefile index a5c9573bed7e347ea336610a010827038c8491c7..af07565b1dbd57b66eff76e79916d120e29c648a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -21,7 +21,7 @@ else VERSION:=unknown (not compiled in a git repository) endif endif -CC_FLAGS += -DVERSION="\"$(VERSION)\"" +CC_FLAGS += -DVERSION="\"$(VERSION)\"" -DSIGNAL CC_FLAGS += -I$(CUDA_PATH)/include diff --git a/src/SignalManager.cpp b/src/SignalManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..30b3688d251a224b57825a5cca156236f898e610 --- /dev/null +++ b/src/SignalManager.cpp @@ -0,0 +1,49 @@ +#include "SignalManager.h" +#include <cstdio> +#include <cstdlib> +#ifdef SIGNAL +#include "common.h" +//#include "ARBDException.h" + +void SignalManager::segfault_handler(int sig, siginfo_t *info, void *secret) +{ + //comment out for now + //if(sig != SIGSEGV) + //throw ARBDException("segfault_handler should handle segmentation faults only, got %d", sig); + void *trace[16]; + char **messages = (char **) NULL; + int i, trace_size = 0; + ucontext_t *uc = (ucontext_t *) secret; + //write to stdout for now + fprintf(stdout, "Segmentation fault identified, faulty address is %p, from %p", info->si_addr, uc->uc_mcontext.gregs[MY_REG_RIP]); + + trace_size = backtrace(trace, 16); + /* overwrite sigaction with caller's address */ + trace[1] = (void *) uc->uc_mcontext.gregs[MY_REG_RIP]; + + messages = backtrace_symbols(trace, trace_size); + /* skip first stack frame (points here) */ + + fprintf(stdout, "Execution path:"); + for (i = 1; i < trace_size; ++i) + fprintf(stdout, "\t[bt] %s\n", messages[i]); + //throw here or just exit ? + exit(0); +} + +void SignalManager::manage_segfault() +{ + struct sigaction sa; + + sa.sa_sigaction = segfault_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + + sigaction(SIGSEGV, &sa, NULL); +} + +#else +void SignalManager::segfault_handler(int sig, siginfo_t *info, void *secret) {} +void SignalManager::manage_segfault() {} + +#endif diff --git a/src/SignalManager.h b/src/SignalManager.h new file mode 100644 index 0000000000000000000000000000000000000000..2276cae3e33c69c63bcf68ade806dbbcca18d297 --- /dev/null +++ b/src/SignalManager.h @@ -0,0 +1,36 @@ +/* + * Some function in namespace to handle the + * signal of segmentation fault. + */ + +#ifndef SIGNALMANAGER_H_ +#define SIGNALMANAGER_H_ + +// see http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l3.html +#include <csignal> +#include <execinfo.h> + +#ifdef SIGNAL +/* get REG_EIP from ucontext.h */ +#ifndef __USE_GNU +#define __USE_GNU +#endif +#include <ucontext.h> + +#if __WORDSIZE == 64 +#define MY_REG_RIP REG_RIP +#else +#define MY_REG_RIP REG_EIP +#endif +#endif + + + +namespace SignalManager +{ + + void segfault_handler(int sig, siginfo_t *info, void *secret); + void manage_segfault(); +} + +#endif /* SIGNALMANAGER_H_ */ diff --git a/src/arbd.cpp b/src/arbd.cpp index a1206407b4053893e6b074325282b7a453f2272c..56b62aeb26101415f072cf275e63ee99d91b63ed 100644 --- a/src/arbd.cpp +++ b/src/arbd.cpp @@ -9,12 +9,16 @@ #include "Configuration.h" #include "GPUManager.h" +#include "SignalManager.h" + // using namespace std; using std::max; const unsigned int kIMDPort = 71992; int main(int argc, char* argv[]) { + SignalManager::manage_segfault(); + if (argc == 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)) { // --help printf("Usage: %s [OPTIONS [ARGS]] CONFIGFILE OUTPUT [SEED]\n", argv[0]);