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
PR 合并指标
PR 指标待抓取

描述

(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 摘要。