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

This happens to me pretty often. I get the "BEGIN not safe after errors--compilation aborted at..." message but there are no errors listed. I'd post the code, but it's 1913 lines long. What I've done in the past is comment out entire sections of code until it compiles, then release lines until it doesn't - to find the errant lines. As you can imagine this is a long and mind-numbingly difficult process. Question is, Is there somewhere that Carp does/can log it's issues? -or- is there a line limit to Perl?

Replies are listed 'Best First'.
Re: No errors listed
by davido (Cardinal) on Oct 29, 2014 at 16:20 UTC

    You could set the environment variable PERLDB_OPTS to AutoTrace, and then invoke the script with the -d option to start it in the debugger. You'll get a pretty big dump, so save it somewhere to look at. If your program terminates during compiletime, the dump will show you everything that happened prior to the termination.


    Dave

Re: No errors listed
by SimonPratt (Friar) on Oct 29, 2014 at 16:57 UTC

    You should definitely be getting errors

    BEGIN { th = "Something"; }

    When I run the above code, I get the following error:
    Can't modify constant item in scalar assignment at C:\test.pl line 3, near ""Something";"
    BEGIN not safe after errors--compilation aborted at C:\test.pl line 4.

    As you can see, this not only tells me where the error occurred, but what the error is. Do you have the full text of all output generated?

Re: No errors listed
by MidLifeXis (Monsignor) on Oct 29, 2014 at 16:57 UTC

    Unless your script is playing some error capture / redirection games with BEGIN and $SIG{__WARN__} and $SIG{__DIE__}, what you are seeing does not make a lot of sense, at least in my experience.

    I am open to correction / education, however. :-)

    --MidLifeXis

Re: No errors listed
by marto (Cardinal) on Oct 29, 2014 at 16:18 UTC

    "This happens to me pretty often."

    Do you have a self contained example which you can post here replicating the problem?

Re: No errors listed
by Laurent_R (Canon) on Oct 29, 2014 at 18:48 UTC
    I think that I have actually seen this a few times, "BEGIN not safe" with no previous error printed, perhaps when playing with redirections although I don't remember the exact conditions under which this happened. The successful solution has been to first compile the code with the -c option:
    $ perl -c my_script.pl
    and then the compile error would be printed.

      Yeah, I think I recall seeing something similar, however your BEGIN not safe message will still give you a line number at the point compilation failed, which you can be reasonably sure is either the point of failure, or the line immediately after the point of failure (probably dependant on how many instructions you are in the habit of piling onto individual lines)

        No really it does not. No line number other than the ones in Carp. Not my code.
Re: No errors listed
by soonix (Chancellor) on Oct 30, 2014 at 00:01 UTC
    I have this problem sometimes, in a script that uses Tk::Carp.
    I comment out the use Tk::Carp statement, fix the error and can put it back in.
Re: No errors listed
by dfdumont (Initiate) on Oct 29, 2014 at 16:28 UTC
    This time the problem was the following line: th = $dbh2->prepare("select c.name,c.extractexpression,c.valuetype from outputs as c where c.commandid='$cmdid'"); Note that there is a problem with the 'variable' at the front. Should have been: $sth = $dbh2->prepare("select c.name,c.extractexpression,c.valuetype from outputs as c where c.commandid='$cmdid'"); So normal typo problem. Still, why no message about bareword?

      How are you loading the module that includes this code? (Or the module that loads the ... that loads the broken code.)

      Leave the syntax error and delete as much code as possible while still keeping the lack of the original error message. This will help you narrow down what is eating the error message (and will likely get you to the point of being able to post a reproduceable example).

      Is this Windows, by any chance? I've seen 'do' fail silently in Windows when the included file has errors, but only sometimes.

      - tye        

        The error is in the main module. There is another loaded, but it's not throwing any errors and is stable code. It is Linux, specifically RHEL 6.5 derivative. I've seen this running similarly lengthy pieces of monolithic code since RHEL 6.0 (Perl 5.10). Never saw it in Perl 5.8
Re: No errors listed
by dfdumont (Initiate) on Nov 09, 2014 at 16:26 UTC
    Here's a much shorter example:
    #! /usr/bin/perl -wd use strict; #use Carp; use DBI; my $dbname = "passive"; my $dbuser = "scand"; my $dbpass = "redacted"; my $dsn = "DBI:mysql:" . $dbname; # Open the database my $dbh = DBI->connect($dsn, $dbuser, $dbpass); unless( defined $dbh ) { warn( "($$) Database connect failed: $DBI::errstr\n" ); } my @userids = (); my @passwords = (); my $sth = $dbh->prepare("SELECT id,userid,passwd FROM credentials"); $sth->execute(); while ( my @row = $sth->fetchrow_array ) { $userids[$row[0]] = $row[1]; $passwords[$row[0]] = $row[2]; } $sth->finish; # $dbh->disconnect opendir( DIR, '/usr/local/bin' ); my @filenames = readdir DIR; closedir DIR; my $userid; for( my $i=0; $i<=$#filenames; ++$i ) { $sth = $dbh->prepare("SELECT id FROM target WHERE note='$filenames +[$i]"); $sth->execute(); my @row = $sth->fetchrow_array; if( defined $row[0] ) { next; } open( FILE, '<', "$filenames[$i]" ); my $line = <FILE>; while( defined $line ) { if( $line =~ /ssh (\w+)\@([\d\.]+)/ ) { my $username = $1; my $ipaddr = $2; if( $username =~ /\$userid/ ) { $userid = 4; } else { $userid=0; for( my $j=0; $j<=$#userids; ++$j ) { if( $username =~ $userids[$j] ) { $userid = $j; last; } } if( $userid == 0 ) { warn "Unknown username encountered: $username\n"; } else { $sth = $dbh->prepare("INSERT INTO target (target,note,cred +,enapwd) VALUES ('$ipaddr','$filename[$i]',$userid,$userid)"); $sth->execute(); } } } } close FILE; } exit 0;

    The error line is 60, the one beginning with "$sth = $dbh->prepare("INSERT INTO target...". I know this because if I comment out just this one line, it compiles without an error. Heres the output I get when I leave it in:

    $ perl -c loader.pl Loading DB routines from perl5db.pl version 1.32 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. BEGIN not safe after errors--compilation aborted at /usr/share/perl5/C +arp/Heavy.pm line 11. Compilation failed in require at /usr/share/perl5/Carp.pm line 33.

    Note that Carp is actually commented out at the top, so DBI is pulling it in. This is ultimately an issue with Carp.

    Any aid identifying what is wrong here, also appreciated :-)

      I get

      Loading DB routines from perl5db.pl version 1.37 Editor support available. Enter h or 'h h' for help, or 'perldoc perldebug' for more help. Global symbol "@filename" requires explicit package name at dberror.pl + line 60. Execution of dberror.pl aborted due to compilation errors. at dberror.pl line 69.
      Update : You need to change this loop too otherwise it processes the first line indefinitely !
      my $line = <FILE>; while( defined $line ) { .. }
      poj

      You didn't say which version of perl you're running, but on 5.18 I get an error message.

      Have you tried not running it under the debugger? i.e. remove -wd from the hash bang line.

      perl -c 1106621.pl Global symbol "@filename" requires explicit package name at 1106621.pl + line 60. 1106621.pl had compilation errors.

      So, just a simple typo.