Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Description
(Seegh-100227.)
Currently the faulthandler module has some state in_PyRuntimeState, including objects, which is shared by all interpreters. Interpreters should be isolated from each other, for a variety of reasons (including the possibility of a per-interpreter GIL). Isolating the module will involve moving some of the state toPyInterpreterState (and, under per-interpreter GIL, guarding other state with a global lock).
Code Analysis:
(expand)
Signals
The module installs handlers for various signals.
(expand)
fatal:
SIGBUS- bus errorSIGILL- illegal instructionSIGFPE- floating point exceptionSIGABRT- abortSIGSEGV- segfault
"user":
- the 5 fatal signals
- others (up to
Py_NSIG)
handlers:
faulthandler_fatal_error(signum)faulthandler_exc_handler()(on Windows)faulthandler_user()
State
Fields
https://github.com/python/cpython/blob/main/Include/internal/pycore_faulthandler.h#L49-L86
https://github.com/python/cpython/blob/main/Include/internal/pycore_runtime.h#L146
raw
cpython/Include/internal/pycore_faulthandler.h
Lines 49 to 86 in62251c3
| struct_faulthandler_runtime_state { | |
| struct { | |
| intenabled; | |
| PyObject*file; | |
| intfd; | |
| intall_threads; | |
| PyInterpreterState*interp; | |
| #ifdefMS_WINDOWS | |
| void*exc_handler; | |
| #endif | |
| }fatal_error; | |
| struct { | |
| PyObject*file; | |
| intfd; | |
| PY_TIMEOUT_Ttimeout_us;/* timeout in microseconds */ | |
| intrepeat; | |
| PyInterpreterState*interp; | |
| intexit; | |
| char*header; | |
| size_theader_len; | |
| /* The main thread always holds this lock. It is only released when | |
| faulthandler_thread() is interrupted before this thread exits, or at | |
| Python exit. */ | |
| PyThread_type_lockcancel_event; | |
| /* released by child thread when joined */ | |
| PyThread_type_lockrunning; | |
| }thread; | |
| #ifdefFAULTHANDLER_USER | |
| structfaulthandler_user_signal*user_signals; | |
| #endif | |
| #ifdefFAULTHANDLER_USE_ALT_STACK | |
| stack_tstack; | |
| stack_told_stack; | |
| #endif | |
| }; |
cpython/Include/internal/pycore_faulthandler.h
Lines 36 to 46 in62251c3
| #ifdefFAULTHANDLER_USER | |
| structfaulthandler_user_signal { | |
| intenabled; | |
| PyObject*file; | |
| intfd; | |
| intall_threads; | |
| intchain; | |
| _Py_sighandler_tprevious; | |
| PyInterpreterState*interp; | |
| }; | |
| #endif/* FAULTHANDLER_USER */ |
tables:
name | type | #ifdef | notes |
|---|---|---|---|
fatal_error | |||
.enabled | bool | "is faulthandler enabled?" | |
.file | PyObject * | only for keeping.fd alive | |
.fd | int | ||
.all_threads | bool | ||
.interp | PyInterpreterState * | show only its threads the one that enabled faulthandler | |
.exc_handler | void * | MS_WINDOWS | |
name | type | #ifdef | notes |
thread | --- | ||
.file | PyObject * | only for keeping.fd alive | |
.fd | int | defaults tosys.stderr | |
.timeout_us | PY_TIMEOUT_T | ||
.repeat | bool | ||
.interp | PyInterpreterState * | show only its threads the one that requested the info | |
.exit | bool | ||
.header | char * | ||
.header_len | size_t | ||
.cancel_event | PyThread_type_lock | ||
.running | PyThread_type_lock | ||
name | type | #ifdef | notes |
user_signals | struct faulthandler_user_signal * | FAULTHANDLER_USER | a dynamically allocated array (Py_NSIG) |
user_signals[signum] | --- | ||
.enabled | bool | ||
.file | PyObject * | ||
.fd | int | ||
.all_threads | bool | ||
.chain | bool | ||
.previous | _Py_sighandler_t | ||
.interp | PyInterpreterState * | show only its threads the one that added the handler | |
name | type | #ifdef | notes |
old_stack | stack_t | FAULTHANDLER_USE_ALT_STACK | |
stack | stack_t | FAULTHANDLER_USE_ALT_STACK |
Usage
simple:
name | context | get | set |
|---|---|---|---|
fatal_error | |||
.enabled | module | faulthandler_is_enabled() | faulthandler_disable_py() |
| signal | faulthandler_fatal_error() | ||
| internal | faulthandler_enable()faulthandler_disable() | faulthandler_enable()faulthandler_disable() | |
.file | module | faulthandler_traverse() | faulthandler_py_enable()faulthandler_traverse() |
| internal | faulthandler_disable() | faulthandler_disable() | |
.fd | module | ||
| signal | faulthandler_fatal_error()faulthandler_exc_handler() | ||
.all_threads | module | faulthandler_py_enable() | |
| signal | faulthandler_fatal_error()faulthandler_exc_handler() | ||
.interp | module | faulthandler_py_enable() | |
| internal | faulthandler_fatal_error()faulthandler_exc_handler() | ||
.exc_handler | internal | faulthandler_enable()faulthandler_disable() | faulthandler_enable()faulthandler_disable() |
name | context | get | set |
thread | |||
.file | module | faulthandler_dump_traceback_later()faulthandler_traverse() | faulthandler_dump_traceback_later()faulthandler_traverse() |
| internal | cancel_dump_traceback_later() | cancel_dump_traceback_later() | |
.fd | |||
| module | faulthandler_dump_traceback_later() | ||
| thread | faulthandler_thread() | ||
.timeout_us | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
.repeat | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
.interp | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
.exit | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
.header | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
| internal | cancel_dump_traceback_later() | cancel_dump_traceback_later() | |
.header_len | module | faulthandler_dump_traceback_later() | |
| thread | faulthandler_thread() | ||
.cancel_event | module | faulthandler_dump_traceback_later() | faulthandler_dump_traceback_later() |
| thread | faulthandler_thread() | ||
| internal | cancel_dump_traceback_later() | ||
.running | module | faulthandler_dump_traceback_later() | faulthandler_dump_traceback_later() |
| thread | faulthandler_thread() | ||
| internal | cancel_dump_traceback_later() | ||
name | context | get | set |
user_signals | module | faulthandler_register_py()faulthandler_unregister_py() | faulthandler_register_py()faulthandler_traverse() |
| C-API | _PyFaulthandler_Fini() | _PyFaulthandler_Fini() | |
| signal | faulthandler_user() | ||
user_signals[signum] | |||
.enabled | module | faulthandler_register_py() | faulthandler_register_py() |
| signal | faulthandler_user() | ||
| internal | faulthandler_unregister() | faulthandler_unregister() | |
.file | module | faulthandler_register_py()faulthandler_traverse() | faulthandler_register_py()faulthandler_traverse() |
| internal | faulthandler_unregister() | faulthandler_unregister() | |
.fd | module | faulthandler_register_py() | |
| signal | faulthandler_user() | ||
| internal | faulthandler_unregister() | ||
.all_threads | module | faulthandler_register_py() | |
| signal | faulthandler_user() | ||
.chain | module | faulthandler_register_py() | |
| signal | faulthandler_user() | ||
.previous | module | faulthandler_register_py() | |
| signal | faulthandler_user() | ||
| internal | faulthandler_unregister() | ||
.interp | module | faulthandler_register_py() | |
| signal | faulthandler_user() | ||
name | context | get | set |
stack | C-API | _PyFaulthandler_Init()_PyFaulthandler_Fini() | |
| internal | faulthandler_enable()faulthandler_register()faulthandler_allocate_stack() | ||
old_stack | C-API | _PyFaulthandler_Fini() |
modify data in complex fields:
name | context | calls |
|---|---|---|
fatal_error .fd | signal | faulthandler_fatal_error() ->faulthandler_dump_traceback()faulthandler_fatal_error() ->_Py_DumpExtensionModules()faulthandler_exc_handler()faulthandler_exc_handler() ->_Py_DumpHexadecimal()faulthandler_exc_handler() ->faulthandler_dump_traceback() |
thread.fd | thread | faulthandler_thread() ->_Py_write_noraise()faulthandler_thread() ->_Py_DumpTracebackThreads() |
thread .cancel_event | module | faulthandler_dump_traceback_later() |
| C-API | _PyFaulthandler_Fini() | |
| thread | faulthandler_thread() | |
| internal | cancel_dump_traceback_later() | |
thread .running | module | faulthandler_dump_traceback_later() |
| thread | faulthandler_thread() | |
| internal | cancel_dump_traceback_later() | |
user_signals[signum] .fd | signal | faulthandler_user() ->faulthandler_dump_traceback() |
stack | C-API | _PyFaulthandler_Init()_PyFaulthandler_Fini() |
| internal | faulthandler_allocate_stack() | |
old_stack | internal | faulthandler_allocate_stack() ->sigaltstack() |
Metadata
Metadata
Assignees
Labels
Projects
Status