66#include <stdio.h>
77#include <frameobject.h> // needed to get members of PyFrameObject
88#define GETOBJ PyObject* obj; if (!PyArg_ParseTuple(args, "O", &obj)) return NULL
9+ #define INIT_HANDLER (handle , msg ) if (signal(SIGSEGV, handle) == SIG_ERR) { \
10+ PyErr_SetString(PyExc_ImportError, msg); \
11+ return NULL; \
12+ }
913static jmp_buf buf ;
1014
1115static PyObject * add_ref (PyObject * self , PyObject * args ) {
@@ -41,10 +45,14 @@ static PyObject* force_set_attr(PyObject* self, PyObject* args) {
4145 Py_RETURN_NONE ;
4246}
4347
44- void handler (int signum ) {
48+ static void sigsegv_handler (int signum ) {
4549 longjmp (buf , 1 );
4650}
4751
52+ static void sigiot_handler (int signum ) {
53+ longjmp (buf , 2 );
54+ }
55+
4856static PyObject * handle (PyObject * self , PyObject * args ) {
4957 PyObject * func ;
5058 PyObject * params = NULL ;
@@ -63,21 +71,31 @@ static PyObject* handle(PyObject* self, PyObject* args) {
6371
6472 if (!params ) params = PyTuple_New (0 );
6573 if (!kwargs ) kwargs = PyDict_New ();
74+ int val = setjmp (buf );
6675
67- if (setjmp ( buf ) ) {
76+ if (val ) {
6877 PyFrameObject * frame = PyEval_GetFrame ();
69- PyCodeObject * code = frame -> f_code ;
70- Py_INCREF (code );
78+ PyObject * name ;
79+ PyCodeObject * code = NULL ;
80+
81+ if (frame ) {
82+ code = frame -> f_code ;
83+ Py_INCREF (code );
84+ name = code -> co_name ;
85+ } else {
86+ name = PyObject_GetAttrString (func , "__name__" );
87+ }
7188
7289 // this is basically a copy of PyFrame_GetCode, which is only available on 3.9+
7390
7491 PyErr_Format (
7592 PyExc_RuntimeError ,
76- "segment violation occured during execution of %S" ,
77- code -> co_name
93+ "%s occured during execution of %S" ,
94+ val == 1 ? "segment violation" : "python aborted" ,
95+ name
7896 );
7997
80- Py_DECREF (code );
98+ if ( code ) Py_DECREF (code );
8199 return NULL ;
82100 }
83101
@@ -105,10 +123,14 @@ static struct PyModuleDef module = {
105123};
106124
107125PyMODINIT_FUNC PyInit__pointers (void ) {
108- if (signal (SIGSEGV , handler ) == SIG_ERR ) {
109- PyErr_SetString (PyExc_RuntimeError , "failed to setup SIGSEGV handler" );
110- return NULL ;
111- }
126+ INIT_HANDLER (
127+ sigiot_handler ,
128+ "cant load _pointers: failed to setup SIGIOT handler"
129+ );
130+ INIT_HANDLER (
131+ sigsegv_handler ,
132+ "cant load _pointers: failed to setup SIGSEGV handler"
133+ );
112134
113135 return PyModule_Create (& module );
114136}
0 commit comments