Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't disable stack trace in Carp::croak() for some reason

Tags:

perl

According to the Carp module documentation, croak() should not produce any stack trace unless $Carp::Verbose evaluates to true. But for some reasone, croak() always behaves like confess() in my environment, i.e. always printing a stack trace, even when it should not..

Here is a test script:

#!/usr/bin/perl

use Modern::Perl;
use Carp;

sub func
{
    say "Carp::Verbose = $Carp::Verbose";
    croak "There should be no stack trace after this message!";
}

sub main
{
    func();
}

main;

And here is the result it produces on my system:

$ ./croak
Carp::Verbose = 0
There should be no stack trace after this message! at ./croak line 8
    main::func() called at ./croak line 13
    main::main() called at ./croak line 16

Maybe someone has encountered this issue or has any clue about the root cause?

Here is some info about my environment:

Ubuntu 12.04 LTS
Linux 3.2.0-27-generic x86_64
perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi

Also I get the same wrong behavior on my SL6 system:

Scientific Linux SL release 6.3 (Carbon)
kernel-2.6.32-279.1.1.el6.x86_64
perl, v5.10.1 (*) built for x86_64-linux-thread-multi
like image 318
Dima Chumak Avatar asked Aug 09 '12 08:08

Dima Chumak


People also ask

How do I disable stack trace?

If you wish to disable this feature, simply append /? showtrace=0 to the URL, and the stack trace should disappear after reloading your browser.

What is croak in Perl?

You use croak when it's something your caller isn't doing right. die "error: $!" indicates the error is on the line where the error occured. croak "error: $!" indicates the error is on the line where the caller called your code.

What is carp in Perl?

The carp function in Perl is the basic equivalent of warn and prints the message to STDERR without actually exiting the script and printing the script name.


2 Answers

One of Carp's rules for which frame of the stack trace to use for the error message is:

  1. Any call from a package to itself is safe.

Since your code doesn't use any packages other than main, and since another rule is that the Carp package itself is safe, Carp can't decide what line of code to use for its error message, so it punts and prints out the whole stack trace.

Oh, it's actually there in the Carp perldoc:

What they do is search the call-stack for a function call stack where thay have not been told that there shouldn't be an error. If every call is marked safe, they give up and give a full stack backtrace instead.

This line in the Carp::short_error_loc function is your smoking gun:

return 0 unless defined($caller);    # What happened?
like image 138
mob Avatar answered Oct 20 '22 01:10

mob


Half an answer: it has something to do with the code being all in the same package. If you call the entry point from a different package, croak works as you expect.

like image 33
daxim Avatar answered Oct 20 '22 00:10

daxim