esharris has asked for the wisdom of the Perl Monks concerning the following question:

An admin updated the modules on our Perl 5.8 system. Now if I have a script that uses CGI::Carp qw(fatalsToBrowser warningsToBrowser), a die call within the script prints out the wrong file name and line number. the file name is (from memory) /usr/local/depot/perl-5.8/5.8.0/ ... Carp.pm and the line number is 301. Why doesn't the dying occur on the appropriate line in my script? My conjecture is that CGI::Carp's version of die is missing a support function.
  • Comment on dying in the wrong place while using CGI::Carp

Replies are listed 'Best First'.
Re: dying in the wrong place while using CGI::Carp
by tachyon (Chancellor) on Dec 24, 2003 at 03:36 UTC

    You might want to try using confess() instad of die to see what is happening in more detail:

    use CGI::Carp qw( confess fatalsToBrowser ); foo( 'Hello', 'Carp' ); sub foo { &bar }; sub bar { &baz } sub baz { confess "Confessing I was called with @_\n" } __DATA__ Content-type: text/html <H1>Software error:</H1> <PRE>Confessing I was called with Hello Carp main::baz called at C:\PROGRA~1\PERLBU~1\debug\spbdtest.cgi line 8 main::bar called at C:\PROGRA~1\PERLBU~1\debug\spbdtest.cgi line 7 main::foo('Hello', 'Carp') called at C:\PROGRA~1\PERLBU~1\debug\sp +bdtest.cgi line 5 </PRE> <P> For help, please send mail to this site's webmaster, giving this error + message and the time and date of the error.

    cheers

    tachyon

Re: dying in the wrong place while using CGI::Carp
by davido (Cardinal) on Dec 24, 2003 at 03:39 UTC
    It's hard to be sure without seeing any code at all, as well as without seeing the actual error message. It sounds like you've got a lot of code, and you don't know really where the error is, so it's probably not practical to post a snippet until you've isolated where the problem is. But posting the actual error message could be helpful.

    Here is my initial theory:

    Update: See my update at the bottom of this post. I think it's more on the mark.

    Your admin may have removed the definition of the CGI::Carp error handling routine that is assigned via CGI::Carp::set_message();

    Here's an example. The following code executes properly if you uncomment the "carp_error" sub's definition. But we are looking for what might cause an error within the Carp module. So leave the error-handling sub commented out...:

    use strict; use warnings; use CGI::Pretty; use CGI::Carp qw( fatalsToBrowser ); BEGIN { # sub carp_error { # my $error_message = shift; # my $cq = new CGI; # print $cq->start_html( "Error" ), # $cq->h1("Error"), # $cq->p( "Sorry, the following error has occurred: " ), # $cq->p( $cq->i( $error_message ) ), # $cq->end_html; # } CGI::Carp::set_message( \&carp_error ); } die $!;

    If you call CGI::Carp::set_message(), passing it a reference to a nonexistant error-handling subroutine, you won't know there's a problem until the main script dies for some reason. And then, CGI::Carp tries to call that error-handling routine. And when the call fails because there is no routine, guess what?....

    Content-type: text/html Undefined subroutine &main::carp_error called at C:/Perl/lib/CGI/Carp. +pm line 45 6.

    Yup, the error message hails back to the Carp module.

    Start by trying to figure out if there is a call to CGI::Carp::set_message(), and no definition of the error routine.

    Update: I looked into the source on CGI::Carp. Line 301 is part of the sub import() definition. So whatever it is that your script is doing, it's causing an error to ripple into the import() method of CGI::Carp. merlyn (in the CB) had a brilliant suggestion (most of his are). ...make sure that you have a semicolon after use CGI::Carp;. Without one, it's possible that Perl is seeing the next line of code (up to the next semicolon) as an export list, causing the error you're seeing deep inside the CGI::Carp module.

    use strict; might catch such an error earlier on by noticing a bareword.


    Dave

      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?
        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