Call vips_shutdown on exit to prevent segfault#1412
Call vips_shutdown on exit to prevent segfault#1412felixbuenemann wants to merge 1 commit intolibvips:masterfrom
Conversation
Register vips_shutdown as an atexit handler to drain the libvips thread pool before Python tears down. Without this, worker threads waiting on a condition variable can try to execute code from unmapped memory during Python's final GC pass, causing an intermittent segfault on exit. The function pointer is cached before registering (same pattern as _remove_log_handler) since ffi lookups can fail during shutdown. Calling vips_shutdown multiple times is safe per the libvips docs, so it doesn't matter if pyvips.shutdown() was already called manually.
|
Do you have a reproducer for this? This change effectively reverts commit libvips/libvips@af61d37 (but for Python only). Note to self: check if commit kleisauke/libvips@f75675f could be an alternative to this. |
|
@kleisauke This happened to me when working on new libvips code the was using |
|
A reproducer would be very helpful. Just to confirm, are you referring to this CI run?https://github.com/libvips/libvips/actions/runs/23707203380/job/69061006825 If so, that was fixed in commit libvips/libvips@efaa772, although the |
|
@kleisauke No, it was unrelated. I can't reproduce the problem anymore. OK if I close this PR? |
|
Feel free to close. IIRC, I've encountered this once with new code as well, but that was due to a missing call to |
Register
vips_shutdownas an atexit handler to drain the libvips thread pool before Python tears down. Without this, worker threads waiting on a condition variable can try to execute code from unmapped memory during Python's final GC pass, causing an intermittent segfault on exit.The function pointer is cached before registering (same pattern as
_remove_log_handler) since ffi lookups can fail during shutdown. Callingvips_shutdownmultiple times is safe per the libvips docs, so it doesn't matter ifpyvips.shutdown()was already called manually.