Isolate the faulthandler Module Between Interpreters
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 36k
- 平均マージ
- 1日 9時間
- マージ済み PR(30日)
- 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 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
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() |
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- 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
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 25/100