Open remicollet opened 3 years ago
(gdb) bt
#0 0x00007ffff7fa0ec0 in ()
#1 0x00007ffff04327de in vips_area_free () at /lib64/libvips.so.42
#2 0x00007ffff0439226 in vips_area_unref () at /lib64/libvips.so.42
#3 0x00007ffff7571ed8 in g_value_unset () at /lib64/libgobject-2.0.so.0
#4 0x00007ffff0448584 in meta_free () at /lib64/libvips.so.42
#5 0x00007ffff7444442 in g_hash_table_remove_all_nodes.part () at /lib64/libglib-2.0.so.0
#6 0x00007ffff74450a3 in g_hash_table_remove_all () at /lib64/libglib-2.0.so.0
#7 0x00007ffff7448822 in g_hash_table_destroy () at /lib64/libglib-2.0.so.0
#8 0x00007ffff0448ad9 in vips.meta_destroy () at /lib64/libvips.so.42
#9 0x00007ffff0441900 in vips_image_finalize () at /lib64/libvips.so.42
#10 0x00007ffff7558a70 in g_object_unref () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff043aaf8 in vips.object_set_member () at /lib64/libvips.so.42
#12 0x00007ffff043adb0 in vips_object_set_property () at /lib64/libvips.so.42
#13 0x00007ffff755a5b6 in object_set_property () at /lib64/libgobject-2.0.so.0
#14 0x00007ffff755c789 in g_object_set_valist () at /lib64/libgobject-2.0.so.0
#15 0x00007ffff755ca44 in g_object_set () at /lib64/libgobject-2.0.so.0
#16 0x00007ffff0431b85 in vips_object_dispose_argument () at /lib64/libvips.so.42
#17 0x00007ffff04350a3 in vips_argument_map () at /lib64/libvips.so.42
#18 0x00007ffff043512b in vips_object_dispose () at /lib64/libvips.so.42
#19 0x00007ffff75589e8 in g_object_unref () at /lib64/libgobject-2.0.so.0
#20 0x00007ffff044017f in vips_cache_remove () at /lib64/libvips.so.42
#21 0x00007ffff044627d in vips_cache_drop_all () at /lib64/libvips.so.42
#22 0x00007ffff046091a in vips_shutdown () at /lib64/libvips.so.42
#23 0x00007ffff7692247 in __run_exit_handlers () at /lib64/libc.so.6
#24 0x00007ffff76923f0 in on_exit () at /lib64/libc.so.6
#25 0x000055555563c261 in main (argc=68, argv=0x555555e21230) at /usr/src/debug/php-7.4.23-1.fc33.remi.x86_64/sapi/cli/php_cli.c:1398
I was able to reproduce this. It only seems to happen when one or more loadable modules are installed. See for example:
$ sudo dnf --setopt=install_weak_deps=False install vips-devel
$ make test > test.log 2>&1 && echo "Succeed" || echo "Failed"
Succeed
$ sudo dnf install vips-jxl vips-magick-im6 vips-openslide vips-poppler
$ make test > test.log 2>&1 && echo "Succeed" || echo "Failed"
Failed
$ grep "FAILED TEST SUMMARY" -B1 -A4 test.log
=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
new_from_buffer works [tests/012.phpt]
can set metadata [tests/042.phpt]
=====================================================================
(Tested on Fedora 34)
Perhaps the loadable module is somehow unloaded prior to vips_shutdown
? Though, the g_module_make_resident
call should ensure that it never gets unloaded.
https://github.com/libvips/libvips/blob/4d079f169103f45c7d866d49a54598be0278e7d6/libvips/module/jxl.c#L75-L77
Let me investigate this further.
It seems that the test suite passes when the ZEND_DONT_UNLOAD_MODULES=1
environment variable is set.
$ ZEND_DONT_UNLOAD_MODULES=1 make test
So, the PHP vips extension (vips.so
) will probably need to link with -Wl,-z,nodelete
. I also had a go with this patch for libvips:
But that resulted in the same segfault.
Linking the extension with -Wl,-z,nodelete
could possibly also result that this code is no longer necessary:
https://github.com/libvips/php-vips-ext/blob/310b02998f6de42549a77e6a2097e343f1da104c/vips.c#L2010-L2043
(untested)
Above hack is only for mod_php, and the segfault occurs with cli sapi
Also notice that it may not work, as in various distribution, PHP use RTLD_NOW (build using --enable-rtld-now for security / safety reasons)
I confirm, building the ext with -Wl,-z,nodelete
avoid the segfault
Great, thanks for confirming. Commit https://github.com/kleisauke/php-vips-ext/commit/f08dc82d066b600cff73720cd040e5d7d50c36eb should ensure that the extension is always linked with -Wl,-z,nodelete
. I'll open a PR for that soon.
In that commit, I've also removed the hack mentioned above, as I think it's no longer needed. However, I couldn't reproduce issue https://github.com/libvips/php-vips/issues/26 with version 1.0.2 of the extension, so I'm not sure if it's completely safe to remove that (maybe it was only needed for older Apache versions?).
BTW, does test 029.phpt
still need to be investigated? I noticed that it is excluded in the spec file, see:
https://git.remirepo.net/cgit/rpms/php/pecl/php-pecl-vips.git/tree/php-pecl-vips.spec?id=e9d2156a981132b47f4f01c852182e54e058831f#n180
Perhaps the vips_error_buffer
contained more errors than expected. If so, we may need to apply the following patch:
diff --git a/tests/029.phpt b/tests/029.phpt
index 1111111..2222222 100644
--- a/tests/029.phpt
+++ b/tests/029.phpt
@@ -14,7 +14,7 @@ can get error messages
$msg = vips_error_buffer();
if ($err == -1 &&
- $msg == "add: not one band or 3 bands\n") {
+ strpos($msg, "add: not one band or 3 bands\n") !== false) {
echo "pass";
}
?>
A (draft-)pull request has been made for this at #44.
Probably since recent changes in libvips
Using PHP 7.4, 8.0 with libvips 8.11.3