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