php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81272 Segfault in var[] after array_slice with JIT
Submitted: 2021-07-18 19:25 UTC Modified: 2021-07-20 12:10 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:4 (100.0%)
Same OS:3 (75.0%)
From: dktapps at pmmp dot io Assigned: dmitry (profile)
Status: Closed Package: JIT
PHP Version: 8.0.8 OS: Windows 10
Private report: No CVE-ID: None
 [2021-07-18 19:25 UTC] dktapps at pmmp dot io
Description:
------------
When running the below script in PHP 8.0, a segfault occurs if opcache JIT is enabled (opcache.jit=1205).

The following settings were used to reproduce the problem:

opcache.enable_cli=1
opcache.jit=1205
opcache.jit_buffer_size=128M

Test script:
---------------
<?php

class WritableBookPage{
	public function __construct(string $text){}
}

class WritableBookBase{


	/**
	 * @var WritableBookPage[]
	 * @phpstan-var list<WritableBookPage>
	 */
	private $pages = [];


	/**
	 * Inserts a new page with the given text and moves other pages upwards.
	 *
	 * @return $this
	 */
	public function insertPage(int $pageId, string $pageText = "") : self{
		if($pageId < 0 || $pageId > count($this->pages)){
			throw new \InvalidArgumentException("Page ID must not be negative");
		}
		$newPages = array_slice($this->pages, 0, $pageId);
		$newPages[] = new WritableBookPage($pageText);
		array_push($newPages, ...array_slice($this->pages, $pageId));
		$this->pages = $newPages;
		return $this;
	}
}

$book = new WritableBookBase;
$book->insertPage(0, "test");


Expected result:
----------------
The script should return with no output with exit code 0.

Actual result:
--------------
A segmentation fault occurs.
In VS, the following stacktrace appears:

>	[Inline Frame] php8ts.dll!zend_hash_real_init_packed_ex(_zend_array *) Line 159	C
 	[Inline Frame] php8ts.dll!_zend_hash_index_add_or_update_i(_zend_array *) Line 1037	C
 	php8ts.dll!zend_hash_next_index_insert(_zend_array * ht, _zval_struct * pData) Line 1104	C
 	[External Code]	
 	php8ts.dll!zend_file_handle_dtor(_zend_file_handle * fh) Line 226	C
 	[External Code]	
 	php8ts.dll!zend_execute(_zend_op_array * op_array, _zval_struct * return_value) Line 58877	C
 	php8ts.dll!zend_execute_scripts(int type, _zval_struct * retval, int file_count, ...) Line 1681	C
 	php8ts.dll!php_execute_script(_zend_file_handle * primary_file) Line 2516	C
 	php.exe!do_cli(int argc, char * * argv) Line 951	C
 	php.exe!main(int argc, char * * argv) Line 1336	C
 	[External Code]	


Additionally, in a Linux debug run (see https://github.com/dktapps/php-8-jit-bugs/runs/3098555756?check_suite_focus=true), the following assertion failure appears:
php: /tmp/php-build/source/8.0.7/Zend/zend_hash.c:987: _zend_hash_index_add_or_update_i: Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed.
Aborted (core dumped)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-20 11:21 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2021-07-20 11:21 UTC] nikic@php.net
Reduced:

function test() {
    $newPages = array_slice([], 0, 0);
    $newPages[] = null;
}

test();

Presumably the case where array_slice() returns an interned empty array is not handled.
 [2021-07-20 12:10 UTC] nikic@php.net
-Assigned To: +Assigned To: dmitry
 [2021-07-20 12:10 UTC] nikic@php.net
SEPARATE_ARRAY currently only does something if MAY_BE_RCN. However, we also need to separate immutable arrays.

I'm not sure how this is intended to work. Should array_slice func info specify MAY_BE_RCN, or should SEPARATE_ARRAY be adjusted to always take possible immutable array into account?
 [2021-07-20 12:41 UTC] git@php.net
Automatic comment on behalf of nikic
Revision: https://github.com/php/php-src/commit/051ff33660858effe0d16137ebcfb9e120051dd5
Log: Fix bug #81272: Fix func info for functions returning EMPTY_ARRAY
 [2021-07-20 12:41 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 11:01:27 2024 UTC