python / python/cpython

Isolate the faulthandler Module Between Interpreters

Offen
#101,509 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

3.12 interpreter-core topic-subinterpreters type-feature
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
36k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

(See gh-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 to PyInterpreterState (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 error
  • SIGILL - illegal instruction
  • SIGFPE - floating point exception
  • SIGABRT - abort
  • SIGSEGV - 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

https://github.com/python/cpython/blob/62251c3da06eb4662502295697f39730565b1717/Include/internal/pycore_faulthandler.h#L49-L86
https://github.com/python/cpython/blob/62251c3da06eb4662502295697f39730565b1717/Include/internal/pycore_faulthandler.h#L36-L46

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 to sys.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()

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit Include/internal/pycore_faulthandler.h und Include/internal/pycore_runtime.h und verfolge dann die aufgeführten Einstiegspunkte wie _PyFaulthandler_Init(), _PyFaulthandler_Fini(), faulthandler_enable() und faulthandler_user(). Ordne jedes gemeinsam genutzte Feld aus den Zustandstabellen seiner Interpreter- oder globalen Zuständigkeit zu und überprüfe, dass der faulthandler-Zustand isoliert ist, ohne das Verhalten der Signal-Handler zu beeinträchtigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, python
Bereich
operating-systems
Issue-Typ
Refactoring
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.