python / python/cpython

Isolate the faulthandler Module Between Interpreters

未關閉
#101,509 1 則留言 2 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

3.12 interpreter-core topic-subinterpreters type-feature
主要語言
Python
星號
77.2k
分支
36k
平均合併
1 天 9 小時
30 天內合併 PR
558

描述

(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()

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 Include/internal/pycore_faulthandler.h 和 Include/internal/pycore_runtime.h 開始,然後追蹤列出的進入點,例如 _PyFaulthandler_Init()、_PyFaulthandler_Fini()、faulthandler_enable() 和 faulthandler_user()。將狀態表中的每個共用欄位對應到其直譯器層級或全域層級的擁有權,並驗證 faulthandler 狀態已隔離,同時不會破壞訊號處理常式的行為。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
c, python
領域
operating-systems
Issue 類型
重構
難度
5/5
預估耗時
一週以上
活躍度
停滯
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。