Трассировка стека с допустимыми аргументами подпрограммы

Возможно ли напечатать "fine" stacktrace с параметрами функции  интерполируется, например Data: Dumper? Вместо последней строки этого

  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

Я хочу видеть

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

Другими словами, замените "ARRAY (0x..)" и "HASH (0x..)" в stacktrace

по их фактическим, полезным значениям.

Ответ 1

Установив свой собственный обработчик сигнала, вы можете настроить вывод, не изменяя способ возникновения ошибок. Devel:: StackTrace обеспечивает удобный доступ к данным трассировки стека.

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

это генерирует вывод, например:

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.