-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Multiple classes using same trait causes function JIT crash #17654
Comments
For future reference, there appears to be a reproducer here: laravel/framework#51360 (comment) <?php
require __DIR__.'/Carbon-3.8.4/autoload.php';
use Carbon\Carbon;
use Carbon\CarbonImmutable;
function testCarbon()
{
for ($i = 0; $i < 1000; $i++) {
Carbon::now()->subHour();
Carbon::now()->addMonth();
}
CarbonImmutable::now()->subDays(4);
}
testCarbon(); |
I reduced it to no longer depend on Carbon. You need to have two different classes using the same trait (with self) to trigger this: <?php
trait TestTrait {
public function addUnit(string $x) {
self::addRawUnit($this, $x);
}
public function addRawUnit(self $data, string $x) {
var_dump($x);
}
}
class Test {
use TestTrait;
}
class Test2 {
use TestTrait;
}
function main()
{
(new Test2)->addUnit("bar");
(new Test)->addUnit("foo");
}
main(); EDIT: the problem is that it uses the same cache slot address between the 2 calls. So presumably the runtime cache pointer is wrong? |
…5 Crash The Application This test has two classes that use the same trait. In function JIT mode the same cache slot will be used. This causes problems because it is primed for the first class and then reused for the second class, resulting in an incorrect type check failure. The current check for a megamorphic trait call requires current_frame to not be NULL, but this is only set in tracing mode and not in function mode. This patch corrects the check.
…5 Crash The Application This test has two classes that use the same trait. In function JIT mode the same cache slot will be used. This causes problems because it is primed for the first class and then reused for the second class, resulting in an incorrect type check failure. The current check for a megamorphic trait call requires current_frame to not be NULL, but this is only set in tracing mode and not in function mode. This patch corrects the check.
* PHP-8.3: Fix GH-17654: Multiple classes using same trait causes function JIT crash
* PHP-8.4: Fix GH-17654: Multiple classes using same trait causes function JIT crash
Description
I'm a Laravel dev, but it seems the bug I discovered today is likely an OPcache JIT bug.
You can read this thread to understand what I mean.
In short words, we have a GitHub Actions server that runs PHPUnit tests. At some point, one of tests failed with a strange error:
The TypeError error message is generated by the core PHP logic and doesn't make a lot of sense. Also, it was not possible to reproduce this error locally and it looked server-specific.
I spent some time and isolated the following framework code that caused the crash:
I also noticed this error is not triggered when OPcache is disabled. I compared OPcache settings between servers and noticed that GitHub Action server uses the following CRTO for some reason: 1235. As soon as I switched to "tracing", the error never showed up again.
I run some additional tests and set opcache.jit in different modes. Here's what I found:
As you can see, modes XX14, XX34, XX15 and XX35 fire errors.
So far this bug looks like OPcache bug, that's why I've reported it here.
Here's our GitHub server info just in case:
PHP Version
PHP 8.3
Operating System
Ubuntu 24.04.1
The text was updated successfully, but these errors were encountered: