static void win32_segv(int signum) { /* NB: stack overflow is not an access violation on Win32 */ { /* A simple customized print of the traceback */ SEXP trace, p, q; int line = 1, i; PROTECT(trace = R_GetTraceback(0)); if(trace != R_NilValue) { REprintf("\nTraceback:\n"); for(p = trace; p != R_NilValue; p = CDR(p), line++) { q = CAR(p); /* a character vector */ REprintf("%2d: ", line); for(i = 0; i < LENGTH(q); i++) REprintf("%s", CHAR(STRING_ELT(q, i))); REprintf("\n"); } UNPROTECT(1); } } num_caught++; if(num_caught < 10) signal(signum, win32_segv); if(signum == SIGILL) error("caught access violation - continue with care"); else error("caught access violation - continue with care"); }
static void sigactionSegv(int signum, siginfo_t *ip, void *context) { char *s; /* First check for stack overflow if we know the stack position. We assume anything within 16Mb beyond the stack end is a stack overflow. */ if(signum == SIGSEGV && (ip != (siginfo_t *)0) && (intptr_t) R_CStackStart != -1) { uintptr_t addr = (uintptr_t) ip->si_addr; intptr_t diff = (R_CStackDir > 0) ? R_CStackStart - addr: addr - R_CStackStart; uintptr_t upper = 0x1000000; /* 16Mb */ if((intptr_t) R_CStackLimit != -1) upper += R_CStackLimit; if(diff > 0 && diff < upper) { REprintf(_("Error: segfault from C stack overflow\n")); jump_to_toplevel(); } } /* need to take off stack checking as stack base has changed */ R_CStackLimit = (uintptr_t)-1; /* Do not translate these messages */ REprintf("\n *** caught %s ***\n", signum == SIGILL ? "illegal operation" : signum == SIGBUS ? "bus error" : "segfault"); if(ip != (siginfo_t *)0) { if(signum == SIGILL) { switch(ip->si_code) { #ifdef ILL_ILLOPC case ILL_ILLOPC: s = "illegal opcode"; break; #endif #ifdef ILL_ILLOPN case ILL_ILLOPN: s = "illegal operand"; break; #endif #ifdef ILL_ILLADR case ILL_ILLADR: s = "illegal addressing mode"; break; #endif #ifdef ILL_ILLTRP case ILL_ILLTRP: s = "illegal trap"; break; #endif #ifdef ILL_COPROC case ILL_COPROC: s = "coprocessor error"; break; #endif default: s = "unknown"; break; } } else if(signum == SIGBUS) switch(ip->si_code) { #ifdef BUS_ADRALN case BUS_ADRALN: s = "invalid alignment"; break; #endif #ifdef BUS_ADRERR /* not on MacOS X, apparently */ case BUS_ADRERR: s = "non-existent physical address"; break; #endif #ifdef BUS_OBJERR /* not on MacOS X, apparently */ case BUS_OBJERR: s = "object specific hardware error"; break; #endif default: s = "unknown"; break; } else switch(ip->si_code) { #ifdef SEGV_MAPERR case SEGV_MAPERR: s = "memory not mapped"; break; #endif #ifdef SEGV_ACCERR case SEGV_ACCERR: s = "invalid permissions"; break; #endif default: s = "unknown"; break; } REprintf("address %p, cause '%s'\n", ip->si_addr, s); } { /* A simple customized print of the traceback */ SEXP trace, p, q; int line = 1, i; PROTECT(trace = R_GetTraceback(0)); if(trace != R_NilValue) { REprintf("\nTraceback:\n"); for(p = trace; p != R_NilValue; p = CDR(p), line++) { q = CAR(p); /* a character vector */ REprintf("%2d: ", line); for(i = 0; i < LENGTH(q); i++) REprintf("%s", CHAR(STRING_ELT(q, i))); REprintf("\n"); } UNPROTECT(1); } } if(R_Interactive) { REprintf("\nPossible actions:\n1: %s\n2: %s\n3: %s\n4: %s\n", "abort (with core dump, if enabled)", "normal R exit", "exit R without saving workspace", "exit R saving workspace"); while(1) { if(R_ReadConsole("Selection: ", ConsoleBuf, CONSOLE_BUFFER_SIZE, 0) > 0) { if(ConsoleBuf[0] == '1') break; if(ConsoleBuf[0] == '2') R_CleanUp(SA_DEFAULT, 0, 1); if(ConsoleBuf[0] == '3') R_CleanUp(SA_NOSAVE, 70, 0); if(ConsoleBuf[0] == '4') R_CleanUp(SA_SAVE, 71, 0); } } } REprintf("aborting ...\n"); R_CleanTempDir(); /* now do normal behaviour, e.g. core dump */ signal(signum, SIG_DFL); raise(signum); }
static void Rserve_eval_cleanup(void *arg) { rs_eval_t *e = (rs_eval_t*) arg; SEXP tb = R_GetTraceback(0); if (tb && tb != R_NilValue) R_PreserveObject((e->traceback = tb)); }