Bug #78502 [Ver]: Segmentation Fault in array_map

From: Date: Fri, 06 Sep 2019 08:46:33 +0000
Subject: Bug #78502 [Ver]: Segmentation Fault in array_map
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-222595@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78502&edit=1 ID: 78502 User updated by: phofstetter at sensational dot ch Reported by: phofstetter at sensational dot ch Summary: Segmentation Fault in array_map Status: Verified Type: Bug Package: Reproducible crash Operating System: macos 10.14, Debian 10 PHP Version: 7.4.0RC1 Block user comment: N Private report: N New Comment: I have bisected the issue and found b36dbdd1dd431d1a21fdb6f2508c7c41b682466c to be the culprit. I tried to naïvely just revert that one commit, but of course other changes happened since then and I'm definitely not good enough to deal with the internals at this level in order to fix the ensuing conflicts. Previous Comments: ------------------------------------------------------------------------ [2019-09-06 08:05:54] nikic@php.net Looks like an icall retval slot ends up pointing into the execute_data frame and clobbers func. ------------------------------------------------------------------------ [2019-09-06 06:45:39] phofstetter at sensational dot ch one last update: This happens independently of whether opcache is loaded or not. ------------------------------------------------------------------------ [2019-09-06 06:41:05] phofstetter at sensational dot ch On Debian 10, the attached test script also crashes with a debugger attached. Here's the backtrace: (gdb) run segv.php Starting program: /opt/php/7.4/bin/php segv.php [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x0000555555a881fb in zend_call_function (fci=fci@entry=0x7fffffffa8a0, fci_cache=fci_cache@entry=0x7fffffffa880) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:681 681 } else if (EG(current_execute_data)->func && (gdb) bt #0 0x0000555555a881fb in zend_call_function (fci=fci@entry=0x7fffffffa8a0, fci_cache=fci_cache@entry=0x7fffffffa880) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:681 #1 0x00005555559c6428 in zif_array_map (execute_data=<optimized out>, return_value=0x7ffff4013350) at /home/crazyhat/downloads/php-7.4.0RC1/ext/standard/array.c:6203 #2 0x0000555555b10820 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:1323 #3 execute_ex (ex=0x7fffffffa8a0) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:53461 #4 0x0000555555a88826 in zend_call_function (fci=fci@entry=0x7fffffffaaf0, fci_cache=<optimized out>, fci_cache@entry=0x7fffffffaad0) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_execute_API.c:816 #5 0x00005555559c6428 in zif_array_map (execute_data=<optimized out>, return_value=0x7ffff4013170) at /home/crazyhat/downloads/php-7.4.0RC1/ext/standard/array.c:6203 #6 0x0000555555b10820 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:1323 #7 execute_ex (ex=0x7fffffffa8a0) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:53461 #8 0x0000555555b16a63 in zend_execute (op_array=0x7ffff407c2a0, return_value=<optimized out>) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend_vm_execute.h:57561 #9 0x0000555555a964c4 in zend_execute_scripts (type=type@entry=8, retval=0x7ffff40130b0, retval@entry=0x0, file_count=file_count@entry=3) at /home/crazyhat/downloads/php-7.4.0RC1/Zend/zend.c:1663 #10 0x0000555555a39fa0 in php_execute_script (primary_file=<optimized out>) at /home/crazyhat/downloads/php-7.4.0RC1/main/main.c:2619 #11 0x0000555555b18a66 in do_cli (argc=2, argv=0x55555677a5d0) at /home/crazyhat/downloads/php-7.4.0RC1/sapi/cli/php_cli.c:961 #12 0x0000555555794239 in main (argc=2, argv=0x55555677a5d0) at /home/crazyhat/downloads/php-7.4.0RC1/sapi/cli/php_cli.c:1352 ------------------------------------------------------------------------ [2019-09-06 06:33:17] phofstetter at sensational dot ch Also happens on Debian 10 ------------------------------------------------------------------------ [2019-09-06 06:12:37] phofstetter at sensational dot ch Description: ------------ The test script attached to this bug report will cause a segmenation fault, however, unfortunately, it doesn't happen when a debubgger is attached(??) pilif@celes:~| ⇒ php --version PHP 7.4.0RC1 (cli) (built: Sep 6 2019 07:35:43) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies pilif@celes:~| ⇒ php segv.php [1] 73522 segmentation fault php segv.php pilif@celes:~| ⇒ Test script: --------------- <?php $tree = [ 'name' => 'a', 'quant' => 1, 'children' => [ ['name' => 'b', 'quant' => 1], ['name' => 'c', 'quant' => 1, 'children' => [ ['name' => 'd', 'quant' => 1], ]], ], ]; function tree_map($tree, $recursive_attr, closure $callback){ if(isset($tree[$recursive_attr])){ $tree[$recursive_attr] = array_map(function($c) use($recursive_attr, $callback){ return tree_map($c, $recursive_attr, $callback); }, $tree[$recursive_attr]); } return $callback($tree); } tree_map($tree, 'children', function ($node) {}); Expected result: ---------------- no segfault Actual result: -------------- segfault. My attempts at getting a proper backtrace were foiled by this not crashing when e debugger is attached. However, a slightly more complicated version of the script produced the following trace in lldb: pilif@celes:~| ⇒ lldb php (lldb) target create "php" Current executable set to 'php' (x86_64). (lldb) run segv.php Process 96419 launched: '/usr/local/bin/php' (x86_64) Process 96419 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x00000001003c2a3c php`zend_leave_helper_SPEC + 60 php`zend_leave_helper_SPEC: -> 0x1003c2a3c <+60>: decl (%rdi) 0x1003c2a3e <+62>: je 0x1003c2a66 ; <+102> 0x1003c2a40 <+64>: movl 0x4(%rdi), %eax 0x1003c2a43 <+67>: cmpl $0xa, %eax Target 0: (php) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) * frame #0: 0x00000001003c2a3c php`zend_leave_helper_SPEC + 60 frame #1: 0x000000010037f4ff php`execute_ex + 35 frame #2: 0x0000000100335102 php`zend_call_function + 1230 frame #3: 0x0000000100256cc0 php`zif_array_map + 448 frame #4: 0x00000001003b0365 php`ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER + 80 frame #5: 0x000000010037f4ff php`execute_ex + 35 frame #6: 0x000000010037f6b7 php`zend_execute + 352 frame #7: 0x0000000100342981 php`zend_execute_scripts + 338 frame #8: 0x00000001002eb7bc php`php_execute_script + 482 frame #9: 0x00000001003c86fb php`do_cli + 3893 frame #10: 0x00000001003c7659 php`main + 1229 frame #11: 0x00007fff644192a5 libdyld.dylib`start + 1 (lldb) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78502&edit=1

« previous php.bugs (#222595) next »