|
1 | 1 | #include "Python.h"
|
| 2 | +#include "pycore_ceval.h" // _PyEval_IsGILEnabled |
2 | 3 | #include "pycore_initconfig.h" // _PyStatus_ERR
|
3 | 4 | #include "pycore_pyerrors.h" // _Py_DumpExtensionModules
|
4 | 5 | #include "pycore_pystate.h" // _PyThreadState_GET()
|
|
27 | 28 | # include <sys/auxv.h> // getauxval()
|
28 | 29 | #endif
|
29 | 30 |
|
| 31 | +/* Sentinel to ignore all_threads on free-threading */ |
| 32 | +#define FT_IGNORE_ALL_THREADS 2 |
30 | 33 |
|
31 | 34 | /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */
|
32 | 35 | #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024)
|
@@ -201,10 +204,13 @@ faulthandler_dump_traceback(int fd, int all_threads,
|
201 | 204 | PyGILState_GetThisThreadState(). */
|
202 | 205 | PyThreadState *tstate = PyGILState_GetThisThreadState();
|
203 | 206 |
|
204 |
| - if (all_threads) { |
| 207 | + if (all_threads == 1) { |
205 | 208 | (void)_Py_DumpTracebackThreads(fd, NULL, tstate);
|
206 | 209 | }
|
207 | 210 | else {
|
| 211 | + if (all_threads == FT_IGNORE_ALL_THREADS) { |
| 212 | + PUTS(fd, "<Cannot show all threads while the GIL is disabled>\n"); |
| 213 | + } |
208 | 214 | if (tstate != NULL)
|
209 | 215 | _Py_DumpTraceback(fd, tstate);
|
210 | 216 | }
|
@@ -271,6 +277,27 @@ faulthandler_disable_fatal_handler(fault_handler_t *handler)
|
271 | 277 | #endif
|
272 | 278 | }
|
273 | 279 |
|
| 280 | +static int |
| 281 | +deduce_all_threads(void) |
| 282 | +{ |
| 283 | +#ifndef Py_GIL_DISABLED |
| 284 | + return fatal_error.all_threads; |
| 285 | +#else |
| 286 | + if (fatal_error.all_threads == 0) { |
| 287 | + return 0; |
| 288 | + } |
| 289 | + // We can't use _PyThreadState_GET, so use the stored GILstate one |
| 290 | + PyThreadState *tstate = PyGILState_GetThisThreadState(); |
| 291 | + if (tstate == NULL) { |
| 292 | + return 0; |
| 293 | + } |
| 294 | + |
| 295 | + /* In theory, it's safe to dump all threads if the GIL is enabled */ |
| 296 | + return _PyEval_IsGILEnabled(tstate) |
| 297 | + ? fatal_error.all_threads |
| 298 | + : FT_IGNORE_ALL_THREADS; |
| 299 | +#endif |
| 300 | +} |
274 | 301 |
|
275 | 302 | /* Handler for SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL signals.
|
276 | 303 |
|
@@ -325,7 +352,7 @@ faulthandler_fatal_error(int signum)
|
325 | 352 | PUTS(fd, "\n\n");
|
326 | 353 | }
|
327 | 354 |
|
328 |
| - faulthandler_dump_traceback(fd, fatal_error.all_threads, |
| 355 | + faulthandler_dump_traceback(fd, deduce_all_threads(), |
329 | 356 | fatal_error.interp);
|
330 | 357 |
|
331 | 358 | _Py_DumpExtensionModules(fd, fatal_error.interp);
|
@@ -401,7 +428,7 @@ faulthandler_exc_handler(struct _EXCEPTION_POINTERS *exc_info)
|
401 | 428 | }
|
402 | 429 | }
|
403 | 430 |
|
404 |
| - faulthandler_dump_traceback(fd, fatal_error.all_threads, |
| 431 | + faulthandler_dump_traceback(fd, deduce_all_threads(), |
405 | 432 | fatal_error.interp);
|
406 | 433 |
|
407 | 434 | /* call the next exception handler */
|
|
0 commit comments