xrdebug / php

Official PHP client library for xrDebug
https://xrdebug.com
Apache License 2.0
222 stars 6 forks source link

Allowed memory size of 536870912 bytes exhausted (tried to allocate 253833216 bytes) #85

Closed eznix86 closed 5 months ago

eznix86 commented 7 months ago

Issue on PHP 8.3.3 Laravel 10.45.1

Snippet:

    Route::get('/dashboard', function () {
        xr(auth()->user());
        return view('dashboard');
    })->name('dashboard');

php.ini:

pcre.jit=0
output_buffering=4096

memory_limit=512M
upload_max_filesize=2M
rodber commented 7 months ago

Hello Bruno. Thanks for reporting this.

Could you check if the issue is on the server or the client? You could try using vdd() instead of xr() to determine if the issue is on the client side.

eznix86 commented 7 months ago

Doing vdd now I get iconv(): Detected an illegal character in input string

    Route::get('/dashboard', function () {
        vdd(auth()->user());
        return view('dashboard');
    })->name('dashboard');
rodber commented 7 months ago

Doesn't look good 😅.

Could you get for me a way to replicate this locally? I need to dig a lot and I'm sure that I can nail it. I just need a basic POC to get into it.

eznix86 commented 7 months ago

I will do that when I am free :)

eznix86 commented 5 months ago

Hey, I am back. Sorry for late reply. Here is my setup:

Here are the steps to install and replicate:

# Install Laravel installer:
composer global require laravel/installer
laravel new fix-xrdebug
cd fix-xrdebug

Prompt answers:

Laravel Jetstream
<Enter> Livewire
<Enter> (Selects nothing)
<Enter> Pest
<Enter>

Now you should have Jetstream with Livewire installed. It will prompt you for a db install, just install sqlite.

npm run dev # to install UI
php artisan serve # to run server or use xampp or anything server you want

It might ask you to generate a secret, you will see a button when you go on the website: for ex. localhost:8080.

composer require --dev xrdebug/php -W
composer dump-autoload
# run xrdebug server on another terminal meanwhile.

Then go on app/web.php then xr(auth()->user()); for the dashboard path ( for ex. at localhost:8080).

Go on <base url>/register or click on register button on home screen and create an account it will make you log in after account creation.

Now you should see the error as explained in the issue.

Note:

rodber commented 5 months ago

This issue is on the underlying library at chevere/var-dump, seems to be related to how it handles circular references. I don't use circular references at that level on my daily work, it will take me a ton of time to debug this.

eznix86 commented 5 months ago

No worries. Why not try debugging it on Laravel itself?

rodber commented 5 months ago

I don't use Laravel and it won't help either, the issue is how VarDump handles known objects, it has a "cache" but at property level, not at the entire debug object. That's why it ends up filling the memory.

eznix86 commented 5 months ago

It's quite a challenge, so you are digging in vardump directly?

rodber commented 5 months ago

It's quite a challenge, so you are digging in vardump directly?

No, var_dump also gets hung by memory limit. For this stuff I need to use Symfony's VarDumper and basically replicate the "one dump per reference" motto instead of dump every reference until the chevere/var-dump limit (which is a nested level of 100).

As Laravel pass the app reference pretty much everywhere, the Chevere VarDump is not aware of all the times it has printed that reference as is only check per property nesting, not context. This means that it prints every app up to 100 nested levels, and on multi-level it does it again so it fills up really quick.

I need to move the know references to a top level dump collector, and simply print #ref instead of circle it every time.

rodber commented 5 months ago

I've nailed this issue.

Tested my new implementation with your POC and it works. It prints a HUGE object (~5200 lines), mostly because it prints the entire protected static resolver Illuminate\Database\DatabaseManager object. I wonder why Symfony's VarDumper omit printing this $resolver? I mean... Which is the point in omitting some properties for a debugger 🤦?

In any case, the solution is on the works.

rodber commented 5 months ago

Fixed in v1.1.0: https://github.com/xrdebug/php/releases/tag/1.1.0