@@ -1975,13 +1975,14 @@ init_sys_streams(PyThreadState *tstate)
1975
1975
1976
1976
1977
1977
static void
1978
- _Py_FatalError_DumpTracebacks (int fd )
1978
+ _Py_FatalError_DumpTracebacks (int fd , PyInterpreterState * interp ,
1979
+ PyThreadState * tstate )
1979
1980
{
1980
1981
fputc ('\n' , stderr );
1981
1982
fflush (stderr );
1982
1983
1983
1984
/* display the current Python stack */
1984
- _Py_DumpTracebackThreads (fd , NULL , NULL );
1985
+ _Py_DumpTracebackThreads (fd , interp , tstate );
1985
1986
}
1986
1987
1987
1988
/* Print the current exception (if an exception is set) with its traceback,
@@ -2079,10 +2080,39 @@ fatal_output_debug(const char *msg)
2079
2080
}
2080
2081
#endif
2081
2082
2083
+
2084
+ static void
2085
+ fatal_error_dump_runtime (FILE * stream , _PyRuntimeState * runtime )
2086
+ {
2087
+ fprintf (stream , "Python runtime state: " );
2088
+ if (runtime -> finalizing ) {
2089
+ fprintf (stream , "finalizing (tstate=%p)" , runtime -> finalizing );
2090
+ }
2091
+ else if (runtime -> initialized ) {
2092
+ fprintf (stream , "initialized" );
2093
+ }
2094
+ else if (runtime -> core_initialized ) {
2095
+ fprintf (stream , "core initialized" );
2096
+ }
2097
+ else if (runtime -> preinitialized ) {
2098
+ fprintf (stream , "preinitialized" );
2099
+ }
2100
+ else if (runtime -> preinitializing ) {
2101
+ fprintf (stream , "preinitializing" );
2102
+ }
2103
+ else {
2104
+ fprintf (stream , "unknown" );
2105
+ }
2106
+ fprintf (stream , "\n" );
2107
+ fflush (stream );
2108
+ }
2109
+
2110
+
2082
2111
static void _Py_NO_RETURN
2083
2112
fatal_error (const char * prefix , const char * msg , int status )
2084
2113
{
2085
- const int fd = fileno (stderr );
2114
+ FILE * stream = stderr ;
2115
+ const int fd = fileno (stream );
2086
2116
static int reentrant = 0 ;
2087
2117
2088
2118
if (reentrant ) {
@@ -2092,45 +2122,48 @@ fatal_error(const char *prefix, const char *msg, int status)
2092
2122
}
2093
2123
reentrant = 1 ;
2094
2124
2095
- fprintf (stderr , "Fatal Python error: " );
2125
+ fprintf (stream , "Fatal Python error: " );
2096
2126
if (prefix ) {
2097
- fputs (prefix , stderr );
2098
- fputs (": " , stderr );
2127
+ fputs (prefix , stream );
2128
+ fputs (": " , stream );
2099
2129
}
2100
2130
if (msg ) {
2101
- fputs (msg , stderr );
2131
+ fputs (msg , stream );
2102
2132
}
2103
2133
else {
2104
- fprintf (stderr , "<message not set>" );
2134
+ fprintf (stream , "<message not set>" );
2105
2135
}
2106
- fputs ("\n" , stderr );
2107
- fflush (stderr ); /* it helps in Windows debug build */
2136
+ fputs ("\n" , stream );
2137
+ fflush (stream ); /* it helps in Windows debug build */
2108
2138
2109
- /* Check if the current thread has a Python thread state
2110
- and holds the GIL */
2111
- PyThreadState * tss_tstate = PyGILState_GetThisThreadState ();
2112
- if (tss_tstate != NULL ) {
2113
- PyThreadState * tstate = _PyThreadState_GET ();
2114
- if (tss_tstate != tstate ) {
2115
- /* The Python thread does not hold the GIL */
2116
- tss_tstate = NULL ;
2117
- }
2118
- }
2119
- else {
2120
- /* Py_FatalError() has been called from a C thread
2121
- which has no Python thread state. */
2139
+ _PyRuntimeState * runtime = & _PyRuntime ;
2140
+ fatal_error_dump_runtime (stream , runtime );
2141
+
2142
+ PyThreadState * tstate = _PyRuntimeState_GetThreadState (runtime );
2143
+ PyInterpreterState * interp = NULL ;
2144
+ if (tstate != NULL ) {
2145
+ interp = tstate -> interp ;
2122
2146
}
2123
- int has_tstate_and_gil = (tss_tstate != NULL );
2124
2147
2148
+ /* Check if the current thread has a Python thread state
2149
+ and holds the GIL.
2150
+
2151
+ tss_tstate is NULL if Py_FatalError() is called from a C thread which
2152
+ has no Python thread state.
2153
+
2154
+ tss_tstate != tstate if the current Python thread does not hold the GIL.
2155
+ */
2156
+ PyThreadState * tss_tstate = PyGILState_GetThisThreadState ();
2157
+ int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate );
2125
2158
if (has_tstate_and_gil ) {
2126
2159
/* If an exception is set, print the exception with its traceback */
2127
2160
if (!_Py_FatalError_PrintExc (fd )) {
2128
2161
/* No exception is set, or an exception is set without traceback */
2129
- _Py_FatalError_DumpTracebacks (fd );
2162
+ _Py_FatalError_DumpTracebacks (fd , interp , tss_tstate );
2130
2163
}
2131
2164
}
2132
2165
else {
2133
- _Py_FatalError_DumpTracebacks (fd );
2166
+ _Py_FatalError_DumpTracebacks (fd , interp , tss_tstate );
2134
2167
}
2135
2168
2136
2169
/* The main purpose of faulthandler is to display the traceback.
0 commit comments