static void sigsegvHandler(int sig, siginfo_t *info, void *secret) { ucontext_t *uc = (ucontext_t*) secret; fprintf(stderr, "Crashed with signal %i\n", sig); void *trace[100]; int trace_size = 0; /* Generate the stack trace */ trace_size = backtrace(trace, 100); /* overwrite sigaction with caller's address */ if (getMcontextEip(uc) != NULL) trace[1] = getMcontextEip(uc); /* Write symbols to log file */ backtrace_symbols_fd(trace, trace_size, 2); /* stderr */ }
/* Logs the stack trace using the backtrace() call. This function is designed * to be called from signal handlers safely. */ static void stacktrace(ucontext_t *uc) { void *trace[100]; char **strings; int trace_size = 0, idx; /* Generate the stack trace */ trace_size = backtrace(trace, 100); /* overwrite sigaction with caller's address */ if (getMcontextEip(uc) != NULL) trace[1] = getMcontextEip(uc); /* Write symbols to log file */ strings = backtrace_symbols(trace, trace_size); for (idx=0; idx<trace_size; ++idx) { LOG_FATAL("%s", strings[idx]); } free(strings); }
static void sigsegvHandler(int sig, siginfo_t* info, void* secret) { if (fatal_error_in_progress) raise(sig); fatal_error_in_progress = 1; unlinkPidFile(); #ifdef DEBUG void* trace[100]; size_t trace_size = backtrace(trace, 100); // overwrite sigaction with caller's address ucontext_t *uc = (ucontext_t*) secret; if (getMcontextEip(uc) != NULL) trace[1] = getMcontextEip(uc); if (!s_stack_filename.empty()) { int stackfd = open(s_stack_filename.c_str(), O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); backtrace_symbols_fd(trace, trace_size, stackfd); } base::Logger::instance()->setAutoFlush(true); LOG(fatal, "Ooops! Got signal (" << sig << "): " << strsignal(sig)); char** messages = backtrace_symbols(trace, trace_size); for (int i = 1; i < trace_size; ++i) LOG(fatal, messages[i]); #endif struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; act.sa_handler = SIG_DFL; sigaction(sig, &act, NULL); raise(sig); }
/* Logs the stack trace using the backtrace() call. This function is designed * to be called from signal handlers safely. */ void logStackTrace(ucontext_t *uc) { void *trace[100]; int trace_size = 0, fd; int log_to_stdout = server.logfile[0] == '\0'; /* Open the log file in append mode. */ fd = log_to_stdout ? STDOUT_FILENO : open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644); if (fd == -1) return; /* Generate the stack trace */ trace_size = backtrace(trace, 100); /* overwrite sigaction with caller's address */ if (getMcontextEip(uc) != NULL) trace[1] = getMcontextEip(uc); /* Write symbols to log file */ backtrace_symbols_fd(trace, trace_size, fd); /* Cleanup */ if (!log_to_stdout) close(fd); }