Closed dunglas closed 1 year ago
I'm not getting a segfault. Are you able to provide a backtrace? Also, do you have a reproducer that does not depend on FrankenPHP?
@nielsdos what system are you using? We reproduced on hosts running on Mac (Apple Silicon) as well as Linux (amd64).
Also, can you try to edit the config or create a file in src/
to ensure that Symfony triggers a cache rebuild?
Usually, you wont see the segfault directly, the server will just be "blocked", but using GDB you can see the segfault occurring in libphp.so
.
Unfortunately, I don't know how to reproduce without FrankenPHP. To have similar conditions, we need to be in a multi-threaded web context. It may be possible to create a similar setup with Apache or NGINX Unit but I'm not. It's also possible that the problem is caused by bad interactions with the Go runtime, but as it works on Debian that's not sure.
Here is a GDB backtrace (unfortunately it isn't very readable because there are no official images containing debug symbols). I'll try to compile on Alpine with debug symbols ASAP.
This looks like an infinite loop in compile_file()
:
I just tried with a custom Alpine image having the debug symbols (https://github.com/dunglas/frankenphp/pull/217), and I cannot reproduce the issue. The only difference I can see between both images is that ours is using the PHP-8.2
dev branch and that official Alpine images set some CFLAGS that we don't (I'll see what happens if I add them). That will not be easy to debug :D
With the official PHP 8.3 Alpine image, we get an error message:
Fatal error: Maximum call stack size of 83792 bytes reached during compilation. Try splitting expression in /app/vendor/symfony/framework-bundle/DependencyInjection/Configuration.php on line 351
The "relevant" lines:
private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
{
$rootNode
->fixXmlConfig('workflow')
->children()
->arrayNode('workflows')
Setting the same CFLAGS as in the official image in the image with debug symbols doesn't change anything: the problem doesn't occur unlike with official images.
I found on Google that the default thread stack size for Alpine is lower than for other distros. So perhaps there's not actually an infinite recursion bug (or something else that takes a lot of stack space), but the stack size is just too small. Can you try overriding the thread stack size and see if that (consistently) helps?
what system are you using?
Linux amd64, nothing special really...
Thanks for the lead @nielsdos, it's indeed a problem related to the default thread stack size on Alpine (I was aware of this difference but didn't think about it when it's actually obvious... sorry).
After reading this very interesting article from @kaniini, I managed to mitigate the issue with FrankenPHP: https://github.com/dunglas/frankenphp/pull/223
However, I wonder if this shouldn't also be fixed in php-src by moving the offending variable (which one?) off the stack. Feel free to close if you think that's not necessary.
Cheers, and thanks again!
Thanks for the lead @nielsdos, it's indeed a problem related to the default thread stack size on Alpine (I was aware of this difference but didn't think about it when it's actually obvious... sorry).
No worries. There's always a lot to take into account and it's easy to say it's obvious in hindsight but getting there is something else of course :p Glad you figured it out :)
However, I wonder if this shouldn't also be fixed in php-src by moving the offending variable (which one?) off the stack. Feel free to close if you think that's not necessary.
For buffer allocations we use a technique where we check if it is reasonably small, then it is put on the stack otherwise it is put on the heap. We do have feature requests / bug reports related to stack overflows due to recursive compilation though, so that alone is not enough. In particular I'm thinking of https://github.com/php/php-src/issues/8315 and https://github.com/php/php-src/issues/11240 (there's at least one more but I can't find it?). So I'm closing this in favor of those issues, especially the recursive compilation one.
Description
When building the Symfony cache using FrankenPHP and PHP ZTS provided by the official Alpine PHP image, a segmentation fault occurs on this line: https://github.com/symfony/symfony/blob/517128f8795d28990134010259585c6d623d087f/src/Symfony/Component/ErrorHandler/DebugClassLoader.php#L296
Symfony basically
include
s a lot of files to build the Dependency Injection Container cache, but this always fails on the same class/file:The issue occurs with Alpine but not with the Debian image. It happens even if opcache is disabled or not installed.
Quick reproducer:
PHP Version
PHP 8.2.10 ZTS
Operating System
Alpine Linux 3.18