/** * Add module data to a struct. * This allows module coders to add data to an existing struct * @param md The module data for the struct to be used * @param key The Key for the key/value pair * @param value The value for the key/value pair, this is what will be stored for you * @return MOD_ERR_OK will be returned on success **/ int moduleAddData(ModuleData ** md, char *key, char *value) { char *mod_name = sstrdup(mod_current_module_name); ModuleData *newData = NULL; ModuleData *tmp = *md; SET_SEGV_LOCATION(); if (!key || !value) { alog(LOG_DEBUG, "debug: A module tried to use ModuleAddData() with one ore more NULL arguments... returning"); do_backtrace(0); free(mod_name); return MOD_ERR_PARAMS; } if (mod_current_module_name == NULL) { alog(LOG_DEBUG, "debug: moduleAddData() called with mod_current_module_name being NULL"); if (denora->debug) { do_backtrace(0); } } moduleDelData(md, key); /* Remove any existing module data for this module with the same key */ newData = malloc(sizeof(ModuleData)); if (!newData) { free(mod_name); return MOD_ERR_MEMORY; } newData->moduleName = sstrdup(mod_name); newData->key = sstrdup(key); newData->value = sstrdup(value); if (tmp) { newData->next = tmp; } else { newData->next = NULL; } *md = newData; free(mod_name); if (denora->debug) { moduleDataDebug(md); } return MOD_ERR_OK; }
void signal_death( int signum, siginfo_t *info, void *secret ) { extern const char *const sys_siglist[]; struct sigaction sa; #ifndef __CYGWIN__ ucontext_t *uc; uc = (ucontext_t *)secret; #endif /* Make it so another bad signal will just KILL it */ sa.sa_handler = SIG_DFL; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGSEGV, &sa, NULL ); sigaction( SIGILL, &sa, NULL ); sigaction( SIGFPE, &sa, NULL ); LogPrint( LOG_CRIT, "Received signal: %s", sys_siglist[signum] ); #ifndef __CYGWIN__ #ifdef OLD_IP LogPrint( LOG_CRIT, "Faulty Address: %p, from %p", info->si_addr, uc->uc_mcontext.gregs[OLD_IP] ); #else LogPrint( LOG_CRIT, "Faulty Address %p, no discernable context", info->si_addr ); #endif #else LogPrint( LOG_CRIT, "Faulty Address %p, no discernable context", info->si_addr ); #endif #ifndef __CYGWIN__ #ifdef OLD_IP do_backtrace( signum, (void *)uc->uc_mcontext.gregs[OLD_IP] ); #else do_backtrace( signum, NULL ); #endif #endif /* Spew all remaining messages */ LogFlushOutput(); cursesAtExit(); /* Kill this thing HARD! */ abort(); }
/** * strdup, replacement so we can trap for "out of memory" * @param oldptr Old Pointer * @param newsize Size of new pointer * @return void */ char *sstrdup(const char *src) { char *ret = NULL; if (src) { #ifdef __STRICT_ANSI__ if ((ret = (char *) malloc(strlen(src) + 1))) {; strlcpy(ret, src, sizeof(ret)); } #else ret = strdup(src); #endif if (!ret) #ifndef _WIN32 raise(SIGUSR1); #else abort(); #endif } else { alog("sstrdup() called with NULL-arg"); if (debug) do_backtrace(0); } return ret; }
/** * Returns the value from a key/value pair set. * This allows module coders to retrive any data they have previuosly stored in any given struct * @param md The module data for the struct to be used * @param key The key to find the data for * @return the value paired to the given key will be returned, or NULL **/ char *moduleGetData(ModuleData ** md, char *key) { char *mod_name = sstrdup(mod_current_module_name); ModuleData *modcurrent = *md; SET_SEGV_LOCATION(); alog(LOG_DEBUG, "debug: moduleGetData %p : key %s", (void *) md, key); alog(LOG_DEBUG, "debug: Current Module %s", mod_name); if (mod_current_module_name == NULL) { alog(LOG_DEBUG, "moduleGetData() called with mod_current_module_name being NULL"); if (denora->debug) { do_backtrace(0); } } while (modcurrent) { if ((stricmp(modcurrent->moduleName, mod_name) == 0) && (stricmp(modcurrent->key, key) == 0)) { free(mod_name); return sstrdup(modcurrent->value); } modcurrent = modcurrent->next; } free(mod_name); return NULL; }
void signal_handler(int sig, siginfo_t* si, void* unused) { TSRMLS_FETCH(); #ifdef DEBUG fprintf(stderr, "In signal handler, PID is %d\n", getpid()); fflush(stderr); #endif if (!BACKTRACE_G(be_nice)) { got_signal = 0; #ifndef ZTS if (EG(current_execute_data)) { #endif do_backtrace(TSRMLS_C); #ifndef ZTS } #endif } else { got_signal = 1; } #ifdef DEBUG fprintf(stderr, "Quit signal handler, PID is %d\n", getpid()); fflush(stderr); #endif }
static void signal_handle(int signum) { switch(signum) { case SIGINT: INFO("User press Ctrl-C, Cancel emms!"); exit(0); case SIGSEGV: INFO("emms will be SIGSEGV kill!"); do_backtrace(); exit(0); case SIGABRT: INFO("emms will be SIGABRT kill!"); do_backtrace(); exit(0); default: INFO("emms receive %d", signum); } }
VOIDSIG signal_segfault(int signum) { if (signum == SIGSEGV) { send_event(EVENT_SIGNAL, 2, "SIGSEGV", "Received SIGSEGV: Segfault"); alog(LOG_NORMAL, "Received SIGSEGV: Segfault"); do_backtrace(1); exit(0); } }
void ProcOnError(BN_PInfo I, int err) { IRCServer_t *server; if( verbose || 1 ) { server = (IRCServer_t *)I->User; LogPrint( LOG_DEBUG, "Event Error : %s (%d) : Server %s", strerror(err), err, server->server ); #if 0 do_backtrace( 0, NULL ); #endif } }
static void save_what_can_be_saved(int sig_num) { const char *logfile; char buf[32]; if (write(2,message,strlen(message))<=0) return; logfile = path_config_get_string(PATH_CONFIG_FILE_CARDPEEK_LOG); if (write(2,logfile,strlen(logfile))<=0) return; if (write(2,signature,strlen(signature))<=0) return; sprintf(buf,"Received signal %i\n",sig_num); if (write(2,buf,strlen(buf))<=0) return; log_printf(LOG_ERROR,"Received signal %i",sig_num); do_backtrace(); log_close_file(); exit(-2); }
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { InitializeBacktrace(); BacktraceContext CurrentCtx; if( ctx == NULL ) { ctx = &CurrentCtx; CurrentCtx.ip = NULL; CurrentCtx.bp = __builtin_frame_address(0); CurrentCtx.sp = __builtin_frame_address(0); CurrentCtx.pid = GetCurrentThreadId(); } do_backtrace( buf, size, ctx ); }
VOIDSIG signal_pipe(int signum) { int32 sum; #ifdef SIGPIPE if (signum == SIGPIPE) { send_event(EVENT_SIGNAL, 2, "SIGPIPE", "Received SIGPIPE: Broken pipe"); alog(LOG_NORMAL, "Received SIGPIPE: Broken pipe"); if (sigpipecount >= 2) { sum = time(NULL) - sigpipetime; if (sum < 3600) { alog(LOG_NORMAL, "This error has happened serval times in less then an hour."); alog(LOG_NORMAL, "This generally means there is a serious problem that you need to address."); alog(LOG_NORMAL, "Denora will now exit"); denora_shutdown(); exit(-1); } else if (sum < 86400) { alog(LOG_NORMAL, "This error has happened serval times in less then 24 period"); alog(LOG_NORMAL, "You should consider restarting or resolveing the issue before continue on"); sigpipecount++; sigpipetime = time(NULL); } else { alog(LOG_NORMAL, "This error has happened serval times in greater then 24 period"); alog(LOG_NORMAL, "Operation is still iffy but lowering the sigpipe count"); sigpipecount--; sigpipetime = time(NULL); } } else { alog(LOG_NORMAL, langstr(ALOG_SIGPIPE_WARNING)); do_backtrace(0); sigpipecount++; sigpipetime = time(NULL); } } #endif }
noinline void my_action(int sig) { my_stopwatch_checkpoint(5); _count = _count + 1; printf(" >> Caught SIGSEGV signal (%d out of %d allowed)\n", _count, NUM_OF_SIGSEGV); // 2012-12-17: In ODE test, maybe the stack environment has been corrupted. // time_t rawtime; struct tm *timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); // printf(" Time: %s", asctime(timeinfo)); // Structure tm is statically allocated. /* Backtrace stuff */ void* array[10]; char** strings; size_t size; size = backtrace(array, 10); if(_count > 1) { printf(" >> Stack contents (level=%ld):\n", size); backtrace_symbols_fd(array, size, 2); } #ifdef UNWIND printf(" >> Stack contents by libunwind\n"); do_backtrace(); printf(" << End of stack contents <<<<<<\n"); #endif if(_count >= NUM_OF_SIGSEGV) { printf("[SIGSEGV_HANDLER] Before aborting, re-calculation has taken place %d times.\n", num_total_retries); abort(); } else { my_stopwatch_stop(5); unsigned long sum1 = GetJmpBufChecksum(&buf), sum2 = GetJmpBufChecksum(&buf_1), sum3 = GetJmpBufChecksum(&buf_2); DBG(printf("Byzantine tolerance of buf. sum: %lu, %lu, %lu.\n", sum1, sum2, sum3)); if(sum1 != sum2 && sum2 == sum3) memcpy(&buf, &buf_1, sizeof(jmp_buf)); else if(sum2 != sum1 && sum1 == sum3) memcpy(&buf_1, &buf, sizeof(jmp_buf)); else if(sum3 != sum2 && sum2 == sum1) memcpy(&buf_2, &buf, sizeof(jmp_buf)); DBG(printf("Now, sum(buf) = %u\n", GetJmpBufChecksum(&buf))); printf("\n"); siglongjmp(buf, 1); } printf(" >> Execution not expected here.\n"); abort(); }
/** * Delete the key/value pair indicated by "key" for the current module. * This allows module coders to remove a previously stored key/value pair. * @param md The module data for the struct to be used * @param key The key to delete the key/value pair for **/ void moduleDelData(ModuleData ** md, char *key) { char *mod_name = sstrdup(mod_current_module_name); ModuleData *modcurrent = *md; ModuleData *prev = NULL; ModuleData *next = NULL; SET_SEGV_LOCATION(); if (mod_current_module_name == NULL) { alog(LOG_DEBUG, "debug: moduleDelData() called with mod_current_module_name being NULL"); if (denora->debug) { do_backtrace(0); } } if (key) { while (modcurrent) { next = modcurrent->next; if ((stricmp(modcurrent->moduleName, mod_name) == 0) && (stricmp(modcurrent->key, key) == 0)) { if (prev) { prev->next = modcurrent->next; } else { *md = modcurrent->next; } free(modcurrent->moduleName); free(modcurrent->key); free(modcurrent->value); modcurrent->next = NULL; free(modcurrent); } else { prev = modcurrent; } prev = modcurrent; modcurrent = next; } } free(mod_name); }
/* Note: this function is usually inlined */ static void x(int i, ...) { do_backtrace(); lib_f(1, &x); }
int main(int argc, char **argv) { int status, pid, pending_sig, optind = 1, state = 1; as = unw_create_addr_space(&_UPT_accessors, 0); if (!as) panic ("unw_create_addr_space() failed"); if (argc == 1) { static char *args[] = {"self", "/bin/ls", "/usr", NULL}; /* automated test case */ argv = args; } else if (argc > 1) while (argv[optind][0] == '-') { if (strcmp(argv[optind], "-v") == 0) ++optind, verbose = 1; else if (strcmp(argv[optind], "-i") == 0) ++optind, trace_mode = INSTRUCTION; /* backtrace at each insn */ else if (strcmp(argv[optind], "-s") == 0) ++optind, trace_mode = SYSCALL; /* backtrace at each syscall */ else if (strcmp(argv[optind], "-t") == 0) /* Execute until raise(SIGUSR1), then backtrace at each insn until raise(SIGUSR2). */ ++optind, trace_mode = TRIGGER; else if (strcmp(argv[optind], "-c") == 0) /* Enable caching of unwind-info. */ ++optind, unw_set_caching_policy(as, UNW_CACHE_GLOBAL); else if (strcmp(argv[optind], "-n") == 0) /* Don't look-up and print symbol names. */ ++optind, print_names = 0; else fprintf(stderr, "unrecognized option: %s\n", argv[optind++]); if (optind >= argc) break; } target_pid = fork(); if (!target_pid) { /* child */ if (!verbose) dup2(open("/dev/null", O_WRONLY), 1); ptrace(PTRACE_TRACEME, 0, 0, 0); if ((argc > 1) && (optind == argc)) { fprintf(stderr, "Need to specify a command line for the child\n"); exit(-1); } execve(argv[optind], argv + optind, environ); _exit(-1); } atexit(target_pid_kill); ui = _UPT_create(target_pid); while (nerrors <= nerrors_max) { pid = wait4(-1, &status, 0, NULL); if (pid == -1) { if (errno == EINTR) continue; panic ("wait4() failed (errno=%d)\n", errno); } pending_sig = 0; if (WIFSIGNALED (status) || WIFEXITED (status) || (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP)) { if (WIFEXITED (status)) { if (WEXITSTATUS (status) != 0) panic ("child's exit status %d\n", WEXITSTATUS(status)); break; } else if (WIFSIGNALED (status)) { if (!killed) panic ("child terminated by signal %d\n", WTERMSIG(status)); break; } else { pending_sig = WSTOPSIG (status); /* Avoid deadlock: */ if (WSTOPSIG (status) == SIGKILL) break; if (trace_mode == TRIGGER) { if (WSTOPSIG (status) == SIGUSR1) state = 0; else if (WSTOPSIG (status) == SIGUSR2) state = 1; } if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2) { static int count = 0; if (count++ > 100) { panic ("Too many child unexpected signals (now %d)\n", WSTOPSIG(status)); killed = 1; } } } } switch (trace_mode) { case TRIGGER: if (state) ptrace(PTRACE_CONT, target_pid, 0, 0); else { do_backtrace(); if (ptrace(PTRACE_SINGLESTEP, target_pid, 0, pending_sig) < 0) { panic ("ptrace(PTRACE_SINGLESTEP) failed (errno=%d)\n", errno); killed = 1; } } break; case SYSCALL: if (!state) do_backtrace(); state ^= 1; ptrace(PTRACE_SYSCALL, target_pid, 0, pending_sig); break; case INSTRUCTION: do_backtrace(); ptrace(PTRACE_SINGLESTEP, target_pid, 0, pending_sig); break; } if (killed) kill(target_pid, SIGKILL); } _UPT_destroy(ui); unw_destroy_addr_space(as); if (nerrors) { printf("FAILURE: detected %d errors\n", nerrors); exit(-1); } if (verbose) printf("SUCCESS\n"); return 0; }
void dump_stack(void) { getCallStack(); ALOGI("-----------------"); do_backtrace(); }
void foo3 () { do_backtrace (); }