Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ PHP NEWS
. Fixed a tracing JIT crash when compiling a side trace for a method of a
class that could not be stored in the inheritance cache. (GH-21710)
(Arnaud, iliaal)
. Fixed bug GH-17626 (JIT corrupts an opline handler when blacklisting a
root trace at the opcache.jit_max_root_traces limit, causing spurious
"Too few arguments" errors and crashes). (RV7PR)

- PDO:
. Fixed a leak when a persistent connection failed a liveness check
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -8780,7 +8780,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
SHM_UNPROTECT();
zend_jit_unprotect();

((zend_op*)opline)->handler =
((zend_op*)(t->opline))->handler =
ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->orig_handler;

ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags &= ~ZEND_JIT_TRACE_JITED;
Expand Down
2 changes: 2 additions & 0 deletions ext/opcache/tests/jit/gh17626.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
function gh17626_callee(string $s) { return strtoupper($s); }
41 changes: 41 additions & 0 deletions ext/opcache/tests/jit/gh17626.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
GH-17626: Opline handler corrupted when a root trace is blacklisted at the max_root_traces limit (fails with --repeat 2)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.revalidate_freq=0
opcache.jit=tracing
opcache.jit_buffer_size=16M
opcache.jit_hot_func=2
opcache.jit_hot_loop=255
opcache.jit_hot_return=255
opcache.jit_hot_side_exit=255
opcache.jit_max_root_traces=2
--EXTENSIONS--
opcache
--FILE--
<?php
namespace GH17626;

// In --repeat 2 the callee is recompiled after the first run, so the function
// guard in the trace compiled for caller() fails with ZEND_JIT_EXIT_INVALIDATE.

require __DIR__ . '/gh17626.inc';

function caller(string $s) {
return gh17626_callee($s) . $s;
}

caller('a');
caller('a');
caller('a');
echo caller('a'), "\n";
echo caller('b'), "\n";

touch(__DIR__ . '/gh17626.inc');
opcache_invalidate(__DIR__ . '/gh17626.inc', true);
?>
--EXPECT--
Aa
Bb
2 changes: 2 additions & 0 deletions ext/opcache/tests/jit/gh17626_002.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
class GH17626GrandParent {}
47 changes: 47 additions & 0 deletions ext/opcache/tests/jit/gh17626_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--TEST--
GH-17626: Opline handler corrupted when a root trace is blacklisted at the max_root_traces limit
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit=tracing
opcache.jit_buffer_size=16M
opcache.jit_hot_func=2
opcache.jit_hot_loop=255
opcache.jit_hot_return=255
opcache.jit_hot_side_exit=255
opcache.jit_max_root_traces=2
--EXTENSIONS--
opcache
--FILE--
<?php
require __DIR__ . '/gh17626_002.inc';

class ParentA extends GH17626GrandParent { public static function m() { return 'A'; } }
class ParentB extends GH17626GrandParent { public static function m() { return 'B'; } }

trait T {
public function run(string $s) {
return parent::m() . $s;
}
}

class A extends ParentA { use T; }
class B extends ParentB { use T; }

$a = new A;
$b = new B;

$a->run('x');
$a->run('x');
$a->run('x');
echo $a->run('x'), "\n";
echo $b->run('y'), "\n";
echo $b->run('y'), "\n";
echo $a->run('x'), "\n";
?>
--EXPECT--
Ax
By
By
Ax
Loading