TL;DR: I have some PHP code that makes use of deprecated dynamic properties. If E_DEPRECATED
is disabled in the .ini
, the code:
- Executes successfully if an
xdebug
session is triggered - Fails (in under a second) with a 502 if an
xdebug
session is not triggered
What does starting an xdebug
session do, and why might this affect how silent deprecation warnings are handled?
A coworker has written a stack of PHP code that, when it runs, causes a 502 Bad Gateway error. When this happens, NGINX writes the following to its error log:
2023/02/01 15:16:46 [error] 405#0: *124 kevent() reported about an closed connection (54: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: *.example.org, request: "POST /a/fixtures/add_user?test_mode=true HTTP/1.1", upstream: "fastcgi://127.0.0.1:9010", host: "test.example.org"
Nothing gets written to the error log specified in php.ini. However, the following gets written to the FPM log:
[01-Feb-2023 16:33:52] WARNING: [pool www] child 21027 exited on signal 11 (SIGSEGV) after 71.459422 seconds from start
[01-Feb-2023 16:33:52] NOTICE: [pool www] child 21123 started
Similarly, in an Apache setup, the server ends up returning nothing, with no error log entries to speak of.
However, if an Xdebug session has been triggered, including if it's triggered via a call to xdebug_break()
, the code runs fine and completes, error-free, without a 502.
The code is too lengthy and reliant on too many libraries to post, and we've had no success in identifying which actual standalone part of the code is failing. We can't replicate the error by running the problematic code by itself, only by running it in situ.
So, what I'm wondering is:
- What does triggering an Xdebug session do? Technically, practically, etc.
- Does it change any state for how PHP is executing, and if so, what might that be? Does it change any INI settings, for instance?
- What could possibly explain code succeeding with Xdebug if it fails without?
Update
The code at fault here appears to be the following from an older version of the Respect/Validation library:
class Email extends AbstractRule
{
public function __construct(?EmailValidator $emailValidator = null)
{
$this->emailValidator = $emailValidator;
}
If this code is run with E_DEPRECATED
, it should emit a deprecation warning regarding dynamic properties:
Deprecated: Creation of dynamic property Respect\Validation\Rules\Email::$emailValidator
In our case, we were running the code with E_DEPRECATED
disabled. I would usually have expected PHP to just execute fine in this case, but for some reason it was having trouble with this deprecation and crashing, as described in the original question.
I'm guessing that starting an xdebug
session changes how deprecation warnings are handled and so, despite not surfacing the deprecation warning to us, was correctly handling it behind the scenes?