@@ -202,8 +202,9 @@ faulthandler_get_fileno(PyObject **file_ptr)
202202static PyThreadState *
203203get_thread_state (void )
204204{
205- PyThreadState * tstate = PyThreadState_Get ();
205+ PyThreadState * tstate = _PyThreadState_UncheckedGet ();
206206 if (tstate == NULL ) {
207+ /* just in case but very unlikely... */
207208 PyErr_SetString (PyExc_RuntimeError ,
208209 "unable to get the current thread state" );
209210 return NULL ;
@@ -234,11 +235,12 @@ faulthandler_dump_traceback(int fd, int all_threads,
234235 PyGILState_GetThisThreadState(). */
235236 tstate = PyGILState_GetThisThreadState ();
236237#else
237- tstate = PyThreadState_Get ();
238+ tstate = _PyThreadState_UncheckedGet ();
238239#endif
239240
240- if (all_threads )
241- _Py_DumpTracebackThreads (fd , interp , tstate );
241+ if (all_threads ) {
242+ (void )_Py_DumpTracebackThreads (fd , NULL , tstate );
243+ }
242244 else {
243245 if (tstate != NULL )
244246 _Py_DumpTraceback (fd , tstate );
@@ -272,7 +274,7 @@ faulthandler_dump_traceback_py(PyObject *self,
272274 return NULL ;
273275
274276 if (all_threads ) {
275- errmsg = _Py_DumpTracebackThreads (fd , tstate -> interp , tstate );
277+ errmsg = _Py_DumpTracebackThreads (fd , NULL , tstate );
276278 if (errmsg != NULL ) {
277279 PyErr_SetString (PyExc_RuntimeError , errmsg );
278280 return NULL ;
@@ -469,7 +471,6 @@ faulthandler_thread(void *unused)
469471{
470472 PyLockStatus st ;
471473 const char * errmsg ;
472- PyThreadState * current ;
473474 int ok ;
474475#if defined(HAVE_PTHREAD_SIGMASK ) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK )
475476 sigset_t set ;
@@ -489,12 +490,9 @@ faulthandler_thread(void *unused)
489490 /* Timeout => dump traceback */
490491 assert (st == PY_LOCK_FAILURE );
491492
492- /* get the thread holding the GIL, NULL if no thread hold the GIL */
493- current = _PyThreadState_UncheckedGet ();
494-
495493 _Py_write_noraise (thread .fd , thread .header , (int )thread .header_len );
496494
497- errmsg = _Py_DumpTracebackThreads (thread .fd , thread .interp , current );
495+ errmsg = _Py_DumpTracebackThreads (thread .fd , thread .interp , NULL );
498496 ok = (errmsg == NULL );
499497
500498 if (thread .exit )
@@ -894,7 +892,7 @@ static PyObject *
894892faulthandler_sigsegv (PyObject * self , PyObject * args )
895893{
896894 int release_gil = 0 ;
897- if (!PyArg_ParseTuple (args , "|i:_read_null " , & release_gil ))
895+ if (!PyArg_ParseTuple (args , "|i:_sigsegv " , & release_gil ))
898896 return NULL ;
899897
900898 if (release_gil ) {
@@ -907,6 +905,49 @@ faulthandler_sigsegv(PyObject *self, PyObject *args)
907905 Py_RETURN_NONE ;
908906}
909907
908+ #ifdef WITH_THREAD
909+ static void
910+ faulthandler_fatal_error_thread (void * plock )
911+ {
912+ PyThread_type_lock * lock = (PyThread_type_lock * )plock ;
913+
914+ Py_FatalError ("in new thread" );
915+
916+ /* notify the caller that we are done */
917+ PyThread_release_lock (lock );
918+ }
919+
920+ static PyObject *
921+ faulthandler_fatal_error_c_thread (PyObject * self , PyObject * args )
922+ {
923+ long thread ;
924+ PyThread_type_lock lock ;
925+
926+ faulthandler_suppress_crash_report ();
927+
928+ lock = PyThread_allocate_lock ();
929+ if (lock == NULL )
930+ return PyErr_NoMemory ();
931+
932+ PyThread_acquire_lock (lock , WAIT_LOCK );
933+
934+ thread = PyThread_start_new_thread (faulthandler_fatal_error_thread , lock );
935+ if (thread == -1 ) {
936+ PyThread_free_lock (lock );
937+ PyErr_SetString (PyExc_RuntimeError , "unable to start the thread" );
938+ return NULL ;
939+ }
940+
941+ /* wait until the thread completes: it will never occur, since Py_FatalError()
942+ exits the process immedialty. */
943+ PyThread_acquire_lock (lock , WAIT_LOCK );
944+ PyThread_release_lock (lock );
945+ PyThread_free_lock (lock );
946+
947+ Py_RETURN_NONE ;
948+ }
949+ #endif
950+
910951static PyObject *
911952faulthandler_sigfpe (PyObject * self , PyObject * args )
912953{
@@ -1065,6 +1106,11 @@ static PyMethodDef module_methods[] = {
10651106 "a SIGSEGV or SIGBUS signal depending on the platform" )},
10661107 {"_sigsegv" , faulthandler_sigsegv , METH_VARARGS ,
10671108 PyDoc_STR ("_sigsegv(release_gil=False): raise a SIGSEGV signal" )},
1109+ #ifdef WITH_THREAD
1110+ {"_fatal_error_c_thread" , faulthandler_fatal_error_c_thread , METH_NOARGS ,
1111+ PyDoc_STR ("fatal_error_c_thread(): "
1112+ "call Py_FatalError() in a new C thread." )},
1113+ #endif
10681114 {"_sigabrt" , faulthandler_sigabrt , METH_NOARGS ,
10691115 PyDoc_STR ("_sigabrt(): raise a SIGABRT signal" )},
10701116 {"_sigfpe" , (PyCFunction )faulthandler_sigfpe , METH_NOARGS ,
0 commit comments