python / python/cpython

`ctypes.util._info_callback` (dl_iterate_phdr) closure causes SIGABRT in child after `os.fork()`

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

還沒有人認領這個 Issue。

extension-modules topic-ctypes type-crash
主要語言
Python
星號
77.2k
分支
35.9k
PR 合併指標
PR 指標待擷取

描述

Crash report

What happened?

ctypes.util._info_callback (dl_iterate_phdr) closure causes SIGABRT in child after os.fork()

Versions: Python 3.14.5, Linux x86_64, libffi 3.4.x (/lib64/libffi.so.8)

Hi all,
I have updated my code library from Python3.9 to 3.14. I have noticed that stopping my Python service produced core dumps. My service has a parent which forks multiple children which use scikit-learn.

I could reproduce a minimal running code with a coredump. Sorry, I am not sure, whether it is threadpoolctl or CPython issue. Thus, I opened an issue at threadpoolctl as well.

Below you will find the structured output summarized by our glorious AI overlords.

Thanks!

Problem

If ctypes.util.find_library() (or ctypes.util.dllist()) is called in a
parent process — which lazily creates and caches the module-level
ctypes.CFUNCTYPE closure ctypes.util._info_callback used by the
dl_iterate_phdr()-based lookup added in gh-119349 — and the process then
calls os.fork(), the forked child reliably SIGABRTs when it later exits
via sys.exit()/Py_Finalize():

abort
dlfree.cold (libffi.so.8)
CThunkObject_dealloc (_ctypes.cpython-314-x86_64-linux-gnu.so)
_Py_Dealloc
dict_dealloc
_Py_Dealloc
PyCData_clear (_ctypes)
PyCFuncPtr_dealloc (_ctypes)
_Py_Dealloc
insertdict.isra.0
_PyModule_ClearDict
finalize_modules
_Py_Finalize
Py_Exit
handle_system_exit
...
Py_RunMain
Py_BytesMain

The abort is inside libffi's own private closure allocator (dlfree in
libffi.so.8), not glibc's malloc (confirmed via MALLOC_CHECK_=3, which
had no effect).

Minimal repro
import os, sys, signal, time
from ctypes.util import find_library

find_library("c")  # creates ctypes.util._info_callback in the parent

def child():
    signal.signal(signal.SIGTERM, lambda s, f: sys.exit(0))
    find_library("c")
    time.sleep(30)

pid = os.fork()
if pid == 0:
    child()
else:
    time.sleep(3)
    os.kill(pid, signal.SIGTERM)
    os.waitpid(pid, 0)

python3.14 repro.pyAborted (core dumped) in the child.

Notes:

  • Calling find_library() alone (no fork) does not crash.
  • os.fork() alone (no prior ctypes.util activity) does not crash.
  • Only the combination — closure created pre-fork, then freed at shutdown
    in the child — reproduces it.
  • This did not occur on Python 3.9, since the dl_iterate_phdr-based
    ctypes.util implementation (gh-119349) did not exist there.
CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

No response

貢獻指南

開啟貢獻指南

從這裡開始

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

研究方向

先從報告中描述的 ctypes.util.find_library()、ctypes.util.dllist() 以及延遲建立的 _info_callback 開始,然後在使用 CPython 3.14 的 Linux 上重現最小的 os.fork() 範例。沿著所示的 libffi 與 _ctypes 釋放路徑追蹤子程序的關閉過程。在 callback 於 fork() 之前建立後,子程序能夠在沒有 SIGABRT 的情況下結束,即表示完成。

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

評估

技術堆疊
python
領域
backend, operating-systems
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
冷清
描述清晰度
基本清楚
新手友好度
38/100

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

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