Index: Python/ceval.c =================================================================== --- Python/ceval.c (révision 66701) +++ Python/ceval.c (copie de travail) @@ -16,6 +16,7 @@ #include "eval.h" #include "opcode.h" #include "structmember.h" +#include "segfault.h" #include @@ -553,6 +554,7 @@ PyObject *retval = NULL; /* Return value */ PyThreadState *tstate = PyThreadState_GET(); PyCodeObject *co; + segfault_frame_t segfault_frame; /* when tracing we set things up so that @@ -801,6 +803,15 @@ goto on_error; } + segfault_enter(&segfault_frame); + err = sigsetjmp(segfault_frame.env, 1); + if (err) { + segfault_set_error(err); + err = 0; + why = WHY_EXCEPTION; + goto on_error; + } + for (;;) { #ifdef WITH_TSC if (inst1 == 0) { @@ -2697,6 +2708,8 @@ /* pop frame */ exit_eval_frame: + segfault_exit(&segfault_frame); + Py_LeaveRecursiveCall(); tstate->frame = f->f_back; Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (révision 66701) +++ Python/pythonrun.c (copie de travail) @@ -17,6 +17,7 @@ #include "ast.h" #include "eval.h" #include "marshal.h" +#include "segfault.h" #ifdef HAVE_SIGNAL_H #include @@ -400,6 +401,7 @@ interp = tstate->interp; /* Disable signal handling */ + PyOS_FiniSegfault(); PyOS_FiniInterrupts(); /* Clear type lookup cache */ @@ -1704,6 +1706,7 @@ PyOS_setsig(SIGXFSZ, SIG_IGN); #endif PyOS_InitInterrupts(); /* May imply initsignal() */ + PyOS_InitSegfault(); } Index: Python/segfault.c =================================================================== --- Python/segfault.c (révision 0) +++ Python/segfault.c (révision 0) @@ -0,0 +1,96 @@ +/** + * Python segmentation fault handler + */ + +#include "Python.h" +#include "segfault.h" + +typedef struct { + int init; + PyObject *segfault_text; + PyObject *fpe_text; + segfault_frame_t *current_frame; +#ifdef SEGFAULT_STACK + char stack[4096]; +#endif +} segfault_t; + +static segfault_t segfault; + +void +segfault_set_error(int signum) +{ + if (signum == SIGFPE) { + PyErr_SetObject(PyExc_ArithmeticError, segfault.fpe_text); + } else { + PyErr_SetObject(PyExc_MemoryError, segfault.segfault_text); + } +} + +static int segfault_install(int signum); + +static void +segfault_handler(int signum) +{ + (void)segfault_install(signum); + siglongjmp(segfault.current_frame->env, signum); +} + +static int +segfault_install(int signum) +{ + struct sigaction context, ocontext; + context.sa_handler = segfault_handler; + sigemptyset(&context.sa_mask); +#ifdef SEGFAULT_STACK + context.sa_flags = SA_RESETHAND | SA_RESTART | SA_ONSTACK; +#else + context.sa_flags = SA_RESETHAND | SA_RESTART; +#endif + if (sigaction(signum, &context, &ocontext) == -1) + return 1; + else + return 0; +} + +void +segfault_enter(segfault_frame_t *frame) +{ + frame->previous = segfault.current_frame; + segfault.current_frame = frame; +} + +void +segfault_exit(segfault_frame_t *frame) +{ + if (segfault.current_frame) + segfault.current_frame = segfault.current_frame->previous; +} + +void +PyOS_InitSegfault(void) +{ +#ifdef SEGFAULT_STACK + stack_t ss; + ss.ss_sp = segfault.stack; + ss.ss_size = sizeof(segfault.stack); + ss.ss_flags = 0; + if( sigaltstack(&ss, NULL)) { + /* FIXME: catch this error */ + } +#endif + + /* FIXME: check errors! */ + segfault.fpe_text = PyString_FromString("SIGFPE"); + segfault.segfault_text = PyString_FromString("segmentation fault"); + (void)segfault_install(SIGFPE); + (void)segfault_install(SIGSEGV); +} + +void +PyOS_FiniSegfault(void) +{ + Py_DECREF(segfault.fpe_text); + Py_DECREF(segfault.segfault_text); +} + Modification de propriétés sur Python/segfault.c ___________________________________________________________________ Nom : svn:eol-style + native Index: Include/segfault.h =================================================================== --- Include/segfault.h (révision 0) +++ Include/segfault.h (révision 0) @@ -0,0 +1,31 @@ + +/* Interface to execute compiled code */ + +#ifndef Py_SEGFAULT_H +#define Py_SEGFAULT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Use a custom stack for signal handlers, especially the segfault handler */ +#define SEGFAULT_STACK + +typedef struct _segfault_frame_t { + sigjmp_buf env; + struct _segfault_frame_t *previous; +} segfault_frame_t; + +void segfault_enter(segfault_frame_t *frame); +void segfault_exit(segfault_frame_t *frame); +void segfault_set_error(int signum); + +void PyOS_InitSegfault(void); +void PyOS_FiniSegfault(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SEGFAULT_H */ Modification de propriétés sur Include/segfault.h ___________________________________________________________________ Nom : svn:eol-style + native Index: Makefile.pre.in =================================================================== --- Makefile.pre.in (révision 66701) +++ Makefile.pre.in (copie de travail) @@ -280,6 +280,7 @@ Python/pymath.o \ Python/pystate.o \ Python/pythonrun.o \ + Python/segfault.o \ Python/structmember.o \ Python/symtable.o \ Python/sysmodule.o \