php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80506 Immediate SIGSEGV upon `ini_set("opcache.jit_debug", 1);`
Submitted: 2020-12-12 05:39 UTC Modified: 2020-12-14 12:34 UTC
From: asmqb7 at gmail dot com Assigned: dmitry (profile)
Status: Closed Package: JIT
PHP Version: 8.0.0 OS: Debian 10.7
Private report: No CVE-ID: None
 [2020-12-12 05:39 UTC] asmqb7 at gmail dot com
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 :)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [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
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=66e390707c664dfd645c0eb48e6602e0fdbefbd0
Log: Fixed bug #80506 (Immediate SIGSEGV upon ini_set(&quot;opcache.jit_debug&quot;, 1))
 [2020-12-14 12:28 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2020-12-14 12:28 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=a12e7affd7053f22f66ee2b6b1f00b6b8f1ca540
Log: Fixed bug #80506 (Immediate SIGSEGV upon ini_set(&quot;opcache.jit_debug&quot;, 1))
 [2020-12-14 12:34 UTC] dmitry@php.net
I was only able to reproduce and fix the crash with opcache.file_cache_only=1

May be you have some other "bad" options combination.
Please check if the commit fixed your crash.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 08 03:01:28 2024 UTC