threadpool_info() before os.fork() causes SIGABRT on child exit (Python 3.13+)
Versions: threadpoolctl 3.6.0, Python 3.14.5, libffi 3.4.x (Linux)
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 open the issue with CPython as well.
Below you will find the structured output summarized by our glorious AI overlords.
Thanks!
Problem
Calling threadpoolctl.threadpool_info() in a parent process before
os.fork(), then letting the forked child exit via sys.exit(), reliably
crashes the child with SIGABRT inside libffi's allocator:
abort
dlfree.cold (libffi.so.8)
CThunkObject_dealloc (_ctypes)
... (Py_Finalize / module teardown) ...
Cause
threadpoolctl imports ctypes.util.find_library. On Python 3.13+,
ctypes.util implements Linux lookups via dl_iterate_phdr() using a
module-level ctypes.CFUNCTYPE closure (ctypes.util._info_callback) that
lives for the process lifetime. If this closure is created in a parent
before fork(), the forked child inherits it via copy-on-write. libffi's
private closure allocator keeps global free-list state that diverges
between parent and child after fork; when the child later frees the
inherited closure at interpreter shutdown, the allocator aborts on
corrupted metadata.
Minimal repro
import os, sys, signal, time
import threadpoolctl
threadpoolctl.threadpool_info() # creates ctypes.util._info_callback
def child():
signal.signal(signal.SIGTERM, lambda s, f: sys.exit(0))
threadpoolctl.threadpool_info()
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.py → Aborted (core dumped).
Does not crash if threadpoolctl.threadpool_info() is only called
after the fork (i.e., not in the parent).
threadpool_info()beforeos.fork()causes SIGABRT on child exit (Python 3.13+)Versions: threadpoolctl 3.6.0, Python 3.14.5, libffi 3.4.x (Linux)
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 open the issue with CPython as well.
Below you will find the structured output summarized by our glorious AI overlords.
Thanks!
Problem
Calling
threadpoolctl.threadpool_info()in a parent process beforeos.fork(), then letting the forked child exit viasys.exit(), reliablycrashes the child with
SIGABRTinside libffi's allocator:Cause
threadpoolctlimportsctypes.util.find_library. On Python 3.13+,ctypes.utilimplements Linux lookups viadl_iterate_phdr()using amodule-level
ctypes.CFUNCTYPEclosure (ctypes.util._info_callback) thatlives for the process lifetime. If this closure is created in a parent
before
fork(), the forked child inherits it via copy-on-write. libffi'sprivate closure allocator keeps global free-list state that diverges
between parent and child after fork; when the child later frees the
inherited closure at interpreter shutdown, the allocator aborts on
corrupted metadata.
Minimal repro
python3.14 repro.py→Aborted (core dumped).Does not crash if
threadpoolctl.threadpool_info()is only calledafter the fork (i.e., not in the parent).