(original) (raw)

Index: Include/segfault.h =================================================================== --- Include/segfault.h (révision 0) +++ Include/segfault.h (révision 0) @@ -0,0 +1,37 @@ + +/* 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; + +typedef struct { + int init; + PyObject *text; + segfault_frame_t *current_frame; +#ifdef SEGFAULT_STACK + char stack[4096]; +#endif +} segfault_t; + +void segfault_enter(segfault_frame_t *frame); +void segfault_exit(segfault_frame_t *frame); +void segfault_set_error(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SEGFAULT_H */ Modification de propriétés sur Include/segfault.h ___________________________________________________________________ Nom : svn:eol-style + native Index: Python/segfault.c =================================================================== --- Python/segfault.c (révision 0) +++ Python/segfault.c (révision 0) @@ -0,0 +1,81 @@ +/** + * Python segmentation fault handler + */ + +#include "Python.h" +#include "segfault.h" + +static segfault_t segfault; + +void +segfault_set_error(void) +{ + PyErr_SetObject(PyExc_MemoryError, segfault.text); +} + +static int segfault_install(void); + +static void +segfault_handler(int sig_num) +{ + (void)segfault_install(); + siglongjmp(segfault.current_frame->env, 1); +} + +static int +segfault_install() +{ + 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(SIGSEGV, &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() +{ +#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 + + segfault.text = PyString_FromString("segmentation fault"); + /* FIXME + if (!segfault.text) ???; + */ + (void)segfault_install(); +} + +void +PyOS_FiniSegfault() +{ + Py_DECREF(segfault.text); +} + Modification de propriétés sur Python/segfault.c ___________________________________________________________________ Nom : svn:eol-style + native Index: Python/ceval.c =================================================================== --- Python/ceval.c (révision 66680) +++ 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,13 @@ goto on_error; } + segfault_enter(&segfault_frame); + if (sigsetjmp(segfault_frame.env, 1)) { + segfault_set_error(); + why = WHY_EXCEPTION; + goto on_error; + } + for (;;) { #ifdef WITH_TSC if (inst1 == 0) { @@ -2697,6 +2706,8 @@ /* pop frame */ exit_eval_frame: + segfault_exit(&segfault_frame); + Py_LeaveRecursiveCall(); tstate->frame = f->f_back; Index: Makefile.pre.in =================================================================== --- Makefile.pre.in (révision 66680) +++ 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 \