in reply to Re: dying in the wrong place while using CGI::Carp
in thread dying in the wrong place while using CGI::Carp

In CGI::Carp, line 301 looks like this: sub realdie { CORE::die (@_); } The updated die calls realdie. With the help of a colleague, we concluded that the program actually dies in the body of this realdie. This is why we see the .../CGI/Carp.pm file name and the 301 line number. If I copy this code to my script and use this subroutine, the problem is duplicated. The script appears to die in the body of new realdie. Do you agree with my diagnosis? Is this a bug in CGI::Carp? How can I fix realdie so I uses the right file and line number?
  • Comment on Re: Re: dying in the wrong place while using CGI::Carp

Replies are listed 'Best First'.
Re: Re: Re: dying in the wrong place while using CGI::Carp
by davido (Cardinal) on Dec 24, 2003 at 21:18 UTC
    As I tear into the internals of CGI::Carp, I find that the die() method calls the realdie() method with un-corrected stack backtrace if the ineval() method evaluates to true, and that will happen if the error occurred within an eval, or if it occurred within a mod_perl script (because mod_perl scripts are evaled, according to CGI::Carp's internal comments). I couldn't quite put together what's going on, but the more I look the more I have to say that you just need to find the problem in your script; you're going to be barking up the wrong tree if you try to find it as a bug in CGI::Carp. It's not there.

    Your script is committing an error that isn't manifesting itself until some point within CGI::Carp's error handling. Sorry, Perl isn't giving you a very helpful line number. But the problem really is going to be in your script.

    Are you able to post your script so we don't have to throw darts at a target in the dark? If you post it as a followup here, be sure to use readmore tags. :)

    By the way, one of the most recent updates to CGI::Carp involves the ineval() method (see the POD for CGI::Carp). Could it be that you've upgraded CGI::Carp and now it's catching something it should have caught before?


    Dave

      Doesn't your initial explanation imply that we uncovered a bug? die doesn't correct the stack trace properly when called within an eval. If a recent update involves the ineval() method, that would explain why the die method use to work until the admin guy updated the module. Anyway, try this code segment. I left work early today, but I was able to recreate the problem on my machine at home.
      #!/usr/bin/perl use strict; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); eval { die "Ouch"; }; if ($@) { print $@, "\n"; } eval { my_die("Ouch"); }; if ($@) { print $@, "\n"; } sub my_die { my ($arg) = @_; if (CGI::Carp::ineval) { $arg = join("", @_); my($file,$line,$id) = CGI::Carp::id(1); $arg .= " at $file line $line." unless $arg=~/\n$/; if ($arg !~ /\n$/) { $arg .= "\n"; } CGI::Carp::realdie $arg; } if (!ref($arg)) { $arg = join("", @_); my($file,$line,$id) = CGI::Carp::id(1); $arg .= " at $file line $line." unless $arg=~/\n$/; &fatalsToBrowser($arg) if $CGI::Carp::WRAP; if (($arg =~ /\n$/) || !exists($ENV{MOD_PERL})) { my $stamp = CGI::Carp::stamp; $arg=~s/^/$stamp/gm; } if ($arg !~ /\n$/) { $arg .= "\n"; } } realdie $arg; }
        While I think that you have stumbled onto an undesirable behavior in CGI::Carp, the bug causing your script to die in the first place is still.... within your script.

        However, that said, here's an interesting observation:

        With CGI::Carp.....

        use CGI::Carp; eval { die "Ouch!" }; print $@, "\n"; __OUTPUT__ Ouch at C:/Perl/lib/CGI/Carp.pm line 312.

        With Carp.pm.....

        use Carp; eval { die "Ouch" }; print $@, "\n"; __OUTPUT__ Ouch at C:\Perl\scripts\mytest.pl line 6.

        And with CORE::die()....

        <p> eval { CORE::die "Ouch" } print $@, "\n"; __OUTPUT__ Ouch at C:\Perl\scripts\mytest.pl line 5.

        The documentation for CGI::Carp says that in the realm of CGI scripts, you can simply replace "use Carp;" with "use CGI::Carp;". You've discovered that it's not quite that simple... their behavior with respect to reporting a fatal that occurred inside an eval is not uniform.


        Dave