|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-03-16 16:53 UTC] Elmar dot Klausmeier at gmail dot com
Description: ------------ I tried this with PHP versions 8.0.3 and 7.4.16. I tried it on Arch Linux 5.11.6 and 4.14.180. So version of PHP and operating system does not seem to matter. I tried php, php-cgi in both versions 7 and 8. I changed php.ini to contain: extension=ffi ffi.enable=true I checked that FFI by itself works. I used printf() from libc.so.6 (the example from the documentation) and j0() from libm.so.6 as examples, and they both produce the desired result -- no crash. Task at hand: Call Cobol (=GnuCobol) from PHP. For this, you have to first call cob_init() or cob_init_nomain(), which initializes GnuCobol. I tried both initialization routines -- always same "segmentation fault". After cob_init() you call your Cobol program, but in our case this does not matter, because segmentation fault comes regardless of called Cobol program. I also tried to call cob_tidy(), the endgame of Cobol, but this also did not change the outcome. It looks that FFI and cob_init() do not like each other. Just for clarity: I can call my Cobol routine, and this Cobol routine produces the desired result, so all is good. It is the end of the execution, which crashes for reasons I do not understand. I use GnuCobol version 3.1.2.0. I looked at source code of cob_init() and cob_init_nomain() and didn't find anything scary there. The source code for cob_init*() is here: https://sourceforge.net/p/gnucobol/code/HEAD/tree/branches/gnucobol-3.x/libcob/common.c The segmentation fault comes after finishing. It is not cob_init() which crashes. It looks like that the cleanup of PHP crashes. I ran the same with gdb and valgrind and they both show that getenv() in libc is unhappy: Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7615dcd in getenv () from /usr/lib/libc.so.6 Below is the output of valgrind when running the same: ==39625== Invalid read of size 2 ==39625== at 0x50AADCD: getenv (in /usr/lib/libc-2.33.so) ==39625== by 0x5A2C3F: ??? (in /usr/bin/php) ==39625== by 0x59C62C: ??? (in /usr/bin/php) ==39625== by 0x5AE5A9: zend_hash_graceful_reverse_destroy (in /usr/bin/php) ==39625== by 0x59D58C: ??? (in /usr/bin/php) ==39625== by 0x535CE7: ??? (in /usr/bin/php) ==39625== by 0x3444BC: ??? (in /usr/bin/php) ==39625== by 0x5093B24: (below main) (in /usr/lib/libc-2.33.so) ==39625== Address 0x86e3028 is not stack'd, malloc'd or (recently) free'd ==39625== ==39625== Jump to the invalid address stated on the next line ==39625== at 0x86AFD20: ??? ==39625== by 0x50A8F7F: ??? (in /usr/lib/libc-2.33.so) ==39625== by 0x50AADCC: getenv (in /usr/lib/libc-2.33.so) ==39625== by 0x5A2C3F: ??? (in /usr/bin/php) ==39625== by 0x59C62C: ??? (in /usr/bin/php) ==39625== by 0x5AE5A9: zend_hash_graceful_reverse_destroy (in /usr/bin/php) ==39625== by 0x59D58C: ??? (in /usr/bin/php) ==39625== by 0x535CE7: ??? (in /usr/bin/php) ==39625== by 0x3444BC: ??? (in /usr/bin/php) ==39625== by 0x5093B24: (below main) (in /usr/lib/libc-2.33.so) ==39625== Address 0x86afd20 is not stack'd, malloc'd or (recently) free'd ==39625== ==39625== ==39625== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==39625== Access not within mapped region at address 0x86AFD20 ==39625== at 0x86AFD20: ??? ==39625== by 0x50A8F7F: ??? (in /usr/lib/libc-2.33.so) ==39625== by 0x50AADCC: getenv (in /usr/lib/libc-2.33.so) ==39625== by 0x5A2C3F: ??? (in /usr/bin/php) ==39625== by 0x59C62C: ??? (in /usr/bin/php) ==39625== by 0x5AE5A9: zend_hash_graceful_reverse_destroy (in /usr/bin/php) ==39625== by 0x59D58C: ??? (in /usr/bin/php) ==39625== by 0x535CE7: ??? (in /usr/bin/php) ==39625== by 0x3444BC: ??? (in /usr/bin/php) ==39625== by 0x5093B24: (below main) (in /usr/lib/libc-2.33.so) This is what ldd says about php and libcob: ldd /bin/php linux-vdso.so.1 (0x00007ffd488dc000) libargon2.so.1 => /usr/lib/libargon2.so.1 (0x00007f6a0f5d8000) libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007f6a0f5b8000) libreadline.so.8 => /usr/lib/libreadline.so.8 (0x00007f6a0f560000) libutil.so.1 => /usr/lib/libutil.so.1 (0x00007f6a0f558000) libm.so.6 => /usr/lib/libm.so.6 (0x00007f6a0f410000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f6a0f408000) libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f6a0f298000) libssl.so.1.1 => /usr/lib/libssl.so.1.1 (0x00007f6a0f200000) libcrypto.so.1.1 => /usr/lib/libcrypto.so.1.1 (0x00007f6a0ef20000) libpcre2-8.so.0 => /usr/lib/libpcre2-8.so.0 (0x00007f6a0ee80000) libz.so.1 => /usr/lib/libz.so.1 (0x00007f6a0ee60000) libonig.so.5 => /usr/lib/libonig.so.5 (0x00007f6a0edc8000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f6a0ebf8000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f6a0ebd0000) libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007f6a0eb58000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f6a10840000) libicuuc.so.68 => /usr/lib/libicuuc.so.68 (0x00007f6a0e968000) liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007f6a0e940000) libicudata.so.68 => /usr/lib/libicudata.so.68 (0x00007f6a0cdf8000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f6a0cc18000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f6a0cbf8000) ldd /lib/libcob.so.4 linux-vdso.so.1 (0x00007ffd33d9c000) libm.so.6 => /usr/lib/libm.so.6 (0x00007fcda4c70000) libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fcda4bd0000) libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007fcda4a60000) libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007fcda49e8000) libdb-5.3.so => /usr/lib/libdb-5.3.so (0x00007fcda4828000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fcda4820000) libc.so.6 => /usr/lib/libc.so.6 (0x00007fcda4650000) /usr/lib64/ld-linux-x86-64.so.2 (0x00007fcda4e50000) libicuuc.so.68 => /usr/lib/libicuuc.so.68 (0x00007fcda4460000) libz.so.1 => /usr/lib/libz.so.1 (0x00007fcda4440000) liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007fcda4418000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fcda43f0000) libicudata.so.68 => /usr/lib/libicudata.so.68 (0x00007fcda28a8000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fcda26c8000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fcda26a8000) Many thanks for taking a look at this. Test script: --------------- <html> <title>Call Cobol from PHP via FFI</title> <body> <?php $cobrt = FFI::cdef("void cob_init_nomain(int,char**); int cob_tidy(void);", "libcob.so.4"); echo "Before calling cob_init():<br>\n"; $cobrt->cob_init_nomain(0,null); ?> </body> </html> Expected result: ---------------- <html> <title>Call Cobol from PHP via FFI</title> <body> Before calling cob_init():<br> </body> </html> Actual result: -------------- <html> <title>Call Cobol from PHP via FFI</title> <body> Before calling cob_init():<br> </body> </html> zsh: segmentation fault (core dumped) php7 phpsqrt.php PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 16:00:01 2025 UTC |
I built PHP from source with --enable-debug. valgrind showed that ==37350== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==37350== Access not within mapped region at address 0x852AD20 ==37350== at 0x852AD20: ??? ==37350== by 0x556EF7F: ??? (in /usr/lib/libc-2.33.so) ==37350== by 0x5570DCC: getenv (in /usr/lib/libc-2.33.so) ==37350== by 0x76BB43: module_destructor (zend_API.c:2629) ==37350== by 0x75EE31: module_destructor_zval (zend.c:782) ==37350== by 0x7777A1: _zend_hash_del_el_ex (zend_hash.c:1330) ==37350== by 0x777880: _zend_hash_del_el (zend_hash.c:1353) ==37350== by 0x779188: zend_hash_graceful_reverse_destroy (zend_hash.c:1807) ==37350== by 0x769390: zend_destroy_modules (zend_API.c:1992) ==37350== by 0x75F582: zend_shutdown (zend.c:1078) ==37350== by 0x6C3F17: php_module_shutdown (main.c:2359) ==37350== by 0x84E46D: main (php_cli.c:1351) ==37350== If you believe this happened as a result of a stack ==37350== overflow in your program's main thread (unlikely but ==37350== possible), you can try to increase the size of the ==37350== main thread stack using the --main-stacksize= flag. ==37350== The main thread stack size used in this run was 8388608. . . . zsh: segmentation fault (core dumped) . . . Looking at the code in Zend/zend_API.c: void module_destructor(zend_module_entry *module) /* {{{ */ { . . . module->module_started=0; if (module->type == MODULE_TEMPORARY && module->functions) { zend_unregister_functions(module->functions, -1, NULL); } #if HAVE_LIBDL if (module->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) { DL_UNLOAD(module->handle); } #endif } /* }}} */ I.e., getenv("ZEND_DONT_UNLOAD_MODULES") controls the dlclose() of the module. Running PHP with ZEND_DONT_UNLOAD_MODULES=1 solves problem. See https://www.phpinternalsbook.com/php7/extensions_design/zend_extensions.html. I still do not understand why unloading the FFI extension with the printf() or j0() example does not crash.