Search code examples
phpxdebugxdebug-3

How to truncate long arguments in stack trace?


I'm trying to control Xdebug's output when memory is exhausted. I find that if a very long string is passed to a function (and then memory is subsequently exhausted) Xdebug dumps the entire parameter in the stack trace without truncation.

Some example code to get a stack trace containing a long string parameter:

<?php
function doStuff( string $data ):void {
    if( strlen($data) > 20 ){
        throw new Exception('Too big!');
    }
}
doStuff( str_repeat('foo',20) );

PHP's normal stack trace from the uncaught exception looks like this:

Stack trace:
#0 /path/to/foo.php(7): doStuff('foofoofoofoofoo...')
#1 {main}

The 60 byte $data argument is neatly truncated to 15 characters plus an ellipsis.

But to get a stack trace after memory exhaustion, I need Xdebug enabled. With Xdebug 3 enabled I don't get truncation of the long argument; I get this:

PHP Stack trace:
PHP   1. {main}() /path/to/foo.php:0
PHP   2. doStuff($data = 'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo') /path/to/foo.php:7

To get this output you'll have to set xdebug.show_exception_trace = On. It's easy enough to see memory exhaustion for real, but this is convenient for posting reproducible code. The trace formatting is the same with unhandleable errors.

I'm not asking how to handle exceptions, or print my own custom stack trace. I'm asking about Xdebug's default output for situations where no error handling can be done.

I've messed around with numerous Xdebug settings and can't seem to control how this is displayed.


Solution

  • Xdebug has the xdebug.var_display_max_data setting for this:

    $ cat /tmp/ff.php

    function doStuff( string $data ):void {
        if( strlen($data) > 20 ){
            throw new Exception('Too big!');
        }
    }
    doStuff( str_repeat('foo',20) );
    

    $ php -dxdebug.var_display_max_data=16 /tmp/ff.php

    Fatal error: Uncaught Exception: Too big! in /tmp/ff.php on line 4
    
    Exception: Too big! in /tmp/ff.php on line 4
    
    Call Stack:
        0.0002     384152   1. {main}() /tmp/ff.php:0
        0.0002     384280   2. doStuff($data = 'foofoofoofoofoof'...) /tmp/ff.php:7