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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dktapps at pmmp dot io
New email:
PHP Version: OS:

 

 [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

Pull Requests

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 Nov 21 13:01:29 2024 UTC