-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Hang when using amphp and tracing JIT #12249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
By the way @dstogov, this issue can be easily reproduced without even using network I/O by running the composite cancellation benchmark in https://github.com/amphp/amp:
|
@dstogov Finally managed to narrow it down to this specific closure execution: https://github.com/revoltphp/event-loop/blob/main/src/EventLoop/Internal/AbstractDriver.php#L593 Replacing that line with a call_user_func fixes the issue. Replacing https://github.com/revoltphp/event-loop/blob/main/src/EventLoop/Internal/AbstractDriver.php#L86 with an indirect closure |
It seems like the actual source of the problem is https://github.com/revoltphp/event-loop/blob/main/src/EventLoop/Internal/AbstractDriver.php#L565, the if is entering when it shouldn't, in fact adding the following assertion fails: if (!isset($this->callbacks[$callback->id]) || !$callback->invokable) {
if (isset($this->callbacks[$callback->id]) && $callback->invokable) {
throw new AssertionError("Impossible");
}
unset($callback);
continue;
} |
In fact it's just the isset, splitting the if just this code can trigger the assertion: if (!isset($this->callbacks[$callback->id])) {
if (isset($this->callbacks[$callback->id])) {
throw new AssertionError("Impossible");
}
unset($callback);
continue;
} |
Very strangely, the first few runs after modifying the file don't trigger the assertion (something to do with mtime maybe?) |
The affected trace seems to be trace 311 from the debug output, the zend bytecode seems correct, let's see if I can find the assembly... https://paste.daniil.it/debug_run
|
Simpler reproducer: <?php
use Revolt\EventLoop;
use Revolt\EventLoop\Driver\UvDriver;
use function Amp\delay;
require 'vendor/autoload.php';
EventLoop::setDriver(new UvDriver);
for ($i = 0; $i < 30; $i++) {
EventLoop::queue(static fn () => null);
fwrite(STDOUT, "$i START\n");
delay(0.0001); // Tick loop to allow resources to be freed.
fwrite(STDOUT, "$i END\n");
} |
OK I think I found the cause, the code in the AbstractDriver class is referencing the |
I had to increase the loop count to 100 to be able to reliably reproduce it. |
Yep, however the phpunit testsuite still seems to fail with your fix if ASAN is enabled (not a JIT bug tho)... |
@danog That's not a bug. If you use ASAN and disable the Zend memory allocator (which you need to do for ASAN to work properly), then |
Actually I was referring to this phpunit failure in amphp/parallel:
Which is caused by a crash of the worker process only when ASAN is used, trying to look into it... |
Turns out it's just a timeout caused by the slowdown in ASAN, which causes the connection attempts in |
Oh and also ping @trowski, mind reporting that bus error segfault you were getting on mac with JIT when running |
Fixed via #12381. Feel free to report the other bus error issue though, preferably in a separate issue though :-) |
Description
Reproducer: https://paste.daniil.it/parallel_jit.tar.xz (run.sh script)
PHP Version
PHP 8.2.10
Operating System
Arch linux
The text was updated successfully, but these errors were encountered: