开发者

stack trace with readable subroutine arguments

Is it possible to print 'fine' stacktrace with function params interpolated, such as Da开发者_Python百科ta::Dumper does? Instead of last line of this

  check_module_auth_cookie........... disabled, ok.
  check_module_auth_ntlm............. no NTLM, ok.
  check_module_auth_opensso.......... no OpenSSO, ok.
  check_module_auth_tinysso.......... no TinySSO, ok.
 checksums........................... SDBM, ok.
  checksum hashes...
   /etc/lighttpd/sites/holding2/docroot/dbm/db_model.sdbm... Couldn't tie SDBM file /etc/lighttpd/sites/holding2/docroot/dbm/db_model.sdbm: Отказано в доступе
 at /var/vh/eludia/Eludia/Content/Checksums/SDBM.pm line 52
        HOLDING::checksum_init('db_model') called at /var/vh/eludia/Eludia/Content/Checksums.pm line 195
        HOLDING::BEGIN() called at /var/vh/eludia/Eludia/Content/Checksums.pm line 206
        eval {...} called at /var/vh/eludia/Eludia/Content/Checksums.pm line 206
        require Eludia/Content/Checksums.pm called at /var/vh/eludia/Eludia.pm line 682
        HOLDING::check_module_checksums() called at /var/vh/eludia/Eludia.pm line 961
        HOLDING::BEGIN() called at /var/vh/eludia/Eludia/Content/Checksums.pm line 206
        eval {...} called at /var/vh/eludia/Eludia/Content/Checksums.pm line 206
        require Eludia.pm called at (eval 74) line 1
        eval 'package HOLDING; require Eludia;' called at /var/vh/eludia/Eludia/Loader.pm line 28
        Eludia::Loader::import('Eludia::Loader', 'ARRAY(0x41cf228)', 'HOLDING', 'HASH(0x41defc8)') called at (eval 72) line 7

I want to see

        Eludia::Loader::import('Eludia::Loader', 
                    [
                                '/var/projects/app', 
                                '/var/projects/submodule'
                    ],
                    'HOLDING',
                    {
                                mail_configuration => {etc..}
                    }
        ) called at (eval 72) line 7

In other words, substitute 'ARRAY(0x..)' and 'HASH(0x..)' in stacktrace

by their actual, useful values.


By setting your own signal handler you can customize the output without having to change how the errors are thrown. The Devel::StackTrace provides convenient access to stack trace data.

use Data::Dumper;
use Devel::StackTrace;

sub FatalErr {
    my ($message) = @_;

    my $trace = new Devel::StackTrace();
    $Data::Dumper::Terse = 1;

    print "$message";
    $trace->next_frame for 1..2;
    while (my $frame = $trace->next_frame) {
        my $arg_str = Dumper($frame->args);
        $arg_str =~ s/^/      /gm;
        $arg_str =~ s/^\s+//;
        printf '    during call to %1$s(%2$s) at %4$s:%5$s', $frame->subroutine, $arg_str, $frame->package, $frame->filename, $frame->line;
        print "\n";
    }
}

BEGIN{ $SIG{__DIE__} = \&FatalErr } # attaches the custom signal handler

this generates output like:

something bad happened at ./dietest.pl line 41.
    during call to stuff::foo() at dietest.pl:46
    during call to things::bar({
        'fruit' => [
                     'apple',
                     'orange',
                     'pear'
                   ],
        'veggies' => [
                       'peas',
                       'carrots'
                     ]
      }
      [
        0,
        1,
        2
      ]
) at dietest.pl:36
something bad happened at ./dietest.pl line 41.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜