|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2020-12-14 12:22 UTC] dmitry@php.net
-Status: Open
+Status: Assigned
-Assigned To:
+Assigned To: dmitry
[2020-12-14 12:28 UTC] dmitry@php.net
[2020-12-14 12:28 UTC] dmitry@php.net
-Status: Assigned
+Status: Closed
[2020-12-14 12:28 UTC] dmitry@php.net
[2020-12-14 12:34 UTC] dmitry@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 05:00:01 2025 UTC |
Description: ------------ While working on a some mildly hot/nested code I idly wondered if PHP 8's JIT was kicking in and how much of an impact it might've been making. Setting 'opcache.jit' to 'off' sadly had no material effect on execution time (oh well), but after poking at the documentation I wanted to play with the debug options, so, I tried setting "opcache.jit_debug" to (1<<0) ('1'), and... ooh. $ php -r 'ini_set("opcache.jit_debug", 1);' Segmentation fault $ php -r 'ini_set("opcache.jit_debug", 1);' Segmentation fault $ php -r 'ini_set("opcache.jit_debug", 1);' Segmentation fault I noticed that using php -n -r "works" because opcache was then not being loaded. I verified that moving all other extensions out of the way and only allowing 10-opcache.ini to load reproduces the crash. After staring at the problem for a bit, I tried $ php -d opcache.jit_debug=1 -r 'print ini_get("opcache.jit_debug")."\n";' 1 which works, then discovered that $ php -d opcache.jit_debug=1 -r 'print ini_get("opcache.jit_debug")."\n"; ini_set("opcache.jit_debug", 0);' 1 Segmentation fault *doesn't*. This leads me to suspect some kind of reinitialization-related issue. IOW, the JIT itself is (?)probably fine. I'm using prebuilt PHP 8.0.0 from by packages.sury.org, installable on Debian using the ~four-liner at https://packages.sury.org/php/README.txt. `apt install php8.0-cli php8.0-{common,cli,opcache}-dbgsym` should provide comparable backtraces. Actual result: -------------- $ strace php -r 'ini_set("opcache.jit_debug", 1);'^C ... openat(AT_FDCWD, "/proc/self/exe", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2606\21\0\0\0\0\0"..., 64) = 64 lseek(3, 4907056, SEEK_SET) = 4907056 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 64) = 64 ... read(3, "\1\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\337J\0\0\0\0\0"..., 64) = 64 close(3) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} --- +++ killed by SIGSEGV +++ Segmentation fault $ gdb --args php -r 'ini_set("opcache.jit_debug", 1);' ... (gdb) run Starting program: /usr/bin/php -r ini_set\(\"opcache.jit_debug\",\ 1\)\; ... Program received signal SIGSEGV, Segmentation fault. 0x00007ffff4f6e88c in zend_jit_disasm_init () at ./ext/opcache/jit/zend_jit_disasm_x86.c:559 559 ./ext/opcache/jit/zend_jit_disasm_x86.c: No such file or directory. (gdb) bt #0 0x00007ffff4f6e88c in zend_jit_disasm_init () at ./ext/opcache/jit/zend_jit_disasm_x86.c:559 #1 0x00007ffff4fb7fc5 in zend_jit_debug_config (old_val=<optimized out>, new_val=new_val@entry=1, stage=stage@entry=16) at ./ext/opcache/jit/zend_jit.c:4147 #2 0x00007ffff4ed92ec in OnUpdateJitDebug (entry=<optimized out>, new_value=<optimized out>, mh_arg1=<optimized out>, mh_arg2=<optimized out>, mh_arg3=<optimized out>, stage=16) at ./ext/opcache/zend_accelerator_module.c:173 #3 0x000055555587c7d3 in zend_alter_ini_entry_ex (name=<optimized out>, new_value=0x555555a3e190, modify_type=modify_type@entry=1, stage=stage@entry=16, force_change=force_change@entry=false) at ./Zend/zend_ini.c:346 #4 0x00005555557469a0 in zif_ini_set (execute_data=<optimized out>, return_value=0x7fffffffd410) at ./ext/standard/basic_functions.c:2128 #5 0x0000555555875a0d in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at ./Zend/zend_vm_execute.h:1234 #6 execute_ex (ex=0x7ffff4fcee72) at ./Zend/zend_vm_execute.h:54505 #7 0x000055555587b53c in zend_execute (op_array=0x7ffff5084000, return_value=0x7fffffffd4d0) at ./Zend/zend_vm_execute.h:58856 #8 0x000055555580459e in zend_eval_stringl (str=<optimized out>, str_len=<optimized out>, retval_ptr=0x0, string_name=<optimized out>) at ./Zend/zend_execute_API.c:1193 #9 0x0000555555804769 in zend_eval_stringl_ex (str=<optimized out>, str_len=<optimized out>, retval_ptr=<optimized out>, string_name=<optimized out>, handle_exceptions=<optimized out>) at ./Zend/zend_execute_API.c:1234 #10 0x00005555558a0a09 in do_cli (argc=3, argv=0x555555a33350) at ./sapi/cli/php_cli.c:979 #11 0x000055555566757b in main (argc=3, argv=0x555555a33350) at ./sapi/cli/php_cli.c:1336 (gdb) For what it's worth, https://github.com/php/php-src/blob/PHP-8.0.0/ext/opcache/jit/zend_jit_disasm_x86.c#L559 says 559 zend_jit_disasm_add_symbol("ZEND_HYBRID_HALT_LABEL", (uint64_t)(uintptr_t)zend_jit_halt_op->handler, sizeof(void*)); which... doesn't look wrong to me at all...? At least not from a naive surface analysis. My one "hmm..." is that it's the last call/line in the function, and that maybe something's happening to/on the stack somehow. My mental model of C is particularly bad in these areas :)