2

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?

Laef
  • 1,086
  • 2
  • 11
  • 27
  • Did you pay attention to this link?: https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html – Jamal Azizbeigi Feb 06 '23 at 20:20
  • @JamalAzizbeigi, fortunately configuring `xdebug` is not an issue! It's configured and runs fine. What I'm wondering is whether `xdebug` changes PHP's state somehow such that code that would otherwise fail suddenly executes fine. Not sure if there's something in particular in that article that relates to that question..? – Laef Feb 06 '23 at 20:26
  • @ Laef, a tiny attention to this article surely is vital for your issue. – Jamal Azizbeigi Feb 06 '23 at 20:30
  • 1
    Maybe xdebug increases the default timeout? Have you tried increasing the execution timeout? – fela Feb 06 '23 at 20:30
  • @fela, good thinking! However, the request 502s near-immediately (less than a second). I've tried increasing the limit just as a test using `ini_set('max_execution_time')` and `set_time_limit()` and the issue persists. – Laef Feb 06 '23 at 20:34
  • I can't speak to the xdebug stuff, and you've probably/hopefully done this already, but have you attempted just putting a `die` as early as possible in the stack, and slowly walk it down until something changes? – Chris Haas Feb 06 '23 at 20:35
  • @ChrisHaas, yes, and we also walked `xdebug_break()` through as well. There's definitely a point mid-code where `die()` stops returning 200s and `xdebug_break()` stops breaking. This got us pretty close to identifying the problematic code, but we were already diving into someone else's library and the results were getting... weird. With more time, we could probably narrow it down further, but at this point we were several hours in and the cut-paste-run-repeat was feeling a little hopeless. I felt a different approach (this question) might be worth a try! – Laef Feb 06 '23 at 20:41
  • Did you try to run the code with the built-in PHP server? ```php -S``` to eliminate the proxy configuration issue? – fela Feb 06 '23 at 20:45
  • I wonder if there is something in the `php.ini` that causes it, is it only on this one file or is it continous across the entire code base? – Jaquarh Feb 06 '23 at 20:56
  • 1
    Have you grepped for `set_error_handler` and `xdebug_` calls everywhere? Maybe one of the libraries is doing something weird. Also, although I understand the logic of the path you are going down, I think it might be a red herring, although you might absolutely get lucky, too. – Chris Haas Feb 06 '23 at 20:56
  • @ChrisHaas, smart idea. But it doesn't look like this is the case. – Laef Feb 06 '23 at 23:09
  • @Jaquarh, it's only on this particular route. Doesn't seem to be a problem directly with `php.ini`! – Laef Feb 06 '23 at 23:10
  • The problem appears to be with a deprecated dynamic property assignment. I've updated the question accordingly, though with this discovery, its remit has now become exceedingly small! – Laef Feb 06 '23 at 23:56
  • Can't help you fix it, but since it was a segmentation fault it's likely a bad pointer (memory overwrite, etc) and xdebug happens to rearrange memory in such a way that it doesn't happen. If you're desperate, you could try building php yourself with symbols and debugging that. Good luck. :) – dschultz Feb 07 '23 at 00:25

0 Answers0