0

I'm trying to work out why this error is coming up in a Perl script:

A fatal error has occured:

    Modification of a read-only value attempted at (eval 7) line 10.

Please enable debugging in setup for more details.

When I run it with this from the command line:

perl -d admin.cgi

the point it dies is:

<p><font face='Tahoma,Arial,Helvetica' size=2>A fatal error has occured:</font></p><blockquote><pre>Modification of a read-only value attempted at (eval 14)[/home/user/public_html/cgi-bin/links/admin/GT/AutoLoader.pm:128] line 10.
</pre></blockquote><p><font face='Tahoma,Arial,Helvetica' size=2>Please enable debugging in setup for more details.</font></p>
Modification of a read-only value attempted at (eval 14)[/home/user/web/example.com/public_html/cgi-bin/links/admin/GT/AutoLoader.pm:128] line 10.
Debugged program terminated.  Use q to quit or R to restart,

Looking at the AutoLoader.pm file, I see this on line 128:

eval "package $pkg;\n#line $linenum$pkg\::$func\n$COMPILE->{$func}";

If I add in a bit more debug:

print "FOO: $pkg ($func)\n";

I then see this when running:

FOO: GT::Template (_call_func)
FOO: GT::CGI (html_escape)
FOO: GT::Base (in_eval)
<p><font face='Tahoma,Arial,Helvetica' size=2>A fatal error has occured:</font></p><blockquote><pre>Modification of a read-only value attempted at (eval 7) line 10.
</pre></blockquote><p><font face='Tahoma,Arial,Helvetica' size=2>Please enable debugging in setup for more details.</font></p>
Modification of a read-only value attempted at (eval 7) line 10.

The script worked fine the whole of yesterday, and I don't think I've changed anything that would cause this- so I'm at a bit of a loss.

UPDATE: After some more digging, I've found its coming from this line in another module:

my $output = $code->($self);

$code seems to be coming from a bit above:

my $root      = $self->{root};
my $full_file = $self->{root} . '/' . $template;
my ($code, $dont_save, $files) = $self->{opt}->{print} == 2
    ? @{$FILE_CACHE_PRINT{$full_file}}{qw/code dont_save files/}
    : @{$FILE_CACHE{$full_file}}{qw/code dont_save files/};

UPDATE 2: As requested, here is the output from print STDERR qq|package $pkg;\n#line $linenum$pkg\::$func\n$COMPILE->{$func}\n|;:

package GT::Base;
#line 538GT::Base::in_eval
sub in_eval {
# -------------------------------------------------------
# Current perl has a variable for it, old perl, we need to look
# through the stack trace. Ugh.
#
    my $ineval;
    if ($] >= 5.005 and !MOD_PERL) { $ineval = defined($^S) ? $^S : (stack_trace('GT::Base',1) =~ /\(eval\)/) }
    elsif (MOD_PERL) {
        my $stack = stack_trace('GT::Base', 1);
        $ineval = $stack =~ m{
            \(eval\)
            (?!
                \s+called\ at\s+
                (?:
                    /dev/null
                |
                    -e
                |
                    /\S*/(?:Apache2?|ModPerl)/(?:Registry(?:Cooker)?|PerlRun)\.pm
                |
                    PerlHandler\ subroutine\ `(?:Apache2?|ModPerl)::Registry
                )
            )
        }x;
    }
    else {
        my $stack = stack_trace('GT::Base', 1);
        $ineval   = $stack =~ /\(eval\)/;
    }
    return $ineval;
}


<p><font face='Tahoma,Arial,Helvetica' size=2>A fatal error has occured:</font></p><blockquote><pre>Modification of a read-only value attempted at (eval 7) line 10.
</pre></blockquote><p><font face='Tahoma,Arial,Helvetica' size=2>Please enable debugging in setup for more details.</font></p>
Modification of a read-only value attempted at (eval 7) line 10.
Andrew Newby
  • 4,941
  • 6
  • 40
  • 81
  • What is `GT::AutoLoader`? Is it your own library? That `eval` expression is odd, but I guess it should work. The error is presumably in whatever the `$COMPILE->{$func}` hash element expands to. Rather than printing individual variables, please print the string that is `eval`ed to make it clearer what is happening. `my $code = "package $pkg;\n#line $linenum$pkg\::$func\n$COMPILE->{$func}"; print "<<$code>>\n"; eval $code;` – Borodin Nov 09 '17 at 09:42
  • @Borodin thanks - yeah it is weird, but it was working fine which is the oddest part. I've updated the question with the debug of `print qq|package $pkg;\n#line $linenum$pkg\::$func\n$COMPILE->{$func}\n|;`. Oh, and GT::AutoLoader is part of a script called `Gossamer Links` (not something I wrote) – Andrew Newby Nov 09 '17 at 09:48
  • Perhaps something in [this page](https://stackoverflow.com/a/42183690/4653379) can help – zdim Nov 09 '17 at 09:55
  • There's no assignment in that code except to lexical variable `$ineval`. I think we're looking in the wrong place. – Borodin Nov 09 '17 at 09:58
  • @Borodin yes maybe. I did comment a bit before, around `my $output = $code->($self);`. The error message really isn't that helpful with the location/line numbers either :( – Andrew Newby Nov 09 '17 at 10:00
  • @zdim thanks - the problem is that this is coming from the core modules (that were working fine). All the user front end is ok, its just this admin.cgi script that's being weird – Andrew Newby Nov 09 '17 at 10:01
  • If it were that `eval` then, because of the `#line` directive, the error message would say `... at GT::Base::in_eval line 538` (the line number will be higher). You need to find the code that is printing the error message (`eval` prints nothing on its own) and add a full stack trace so that you can see the call chain. – Borodin Nov 09 '17 at 10:24
  • @Borodin - yeah - after digging deeper and deeper, I found that the Config file was updated by a script (see my answer below). It was trying to do: `FOO: (db_cgi_url) SCALAR(0x250d6e8)` - and the fact it was the SCALAR caused it to fatal on `$t->{"cfg_$key"} = $Links::IN->html_escape($val);` ... not the easiest thing to find! Thanks for your help though :) – Andrew Newby Nov 09 '17 at 10:30

1 Answers1

1

Ah man - found it! In the site config, it had this weird stuff going on:

'db_cgi_url' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url.' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url..' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url...' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url....' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url.....' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url......' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url.......' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url........' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url.........' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url..........' => \'http://m.example.com/cgi-bin/links',
'db_cgi_url...........' => \'http://m.example.com/cgi-bin/links',

Something somewhere else must be updating it, without me asking it to. The front end not under mod_perl seemed ok due to the fact it was using a cached version of Data.pm

Thanks everyone!

Andrew Newby
  • 4,941
  • 6
  • 40
  • 81
  • Hah! Well done. Now you need to find *what* is updating the config – Borodin Nov 09 '17 at 10:32
  • @Borodin yeah! I have a feeling its this from one of the scripts on our mobile version: `$CFG->{db_cgi_url} = "http://m.example.com/cgi-bin/links";`. Its a bit of a PITA, because if you update $CFG while a site build is going , mod_perl can cache it and then store the new variable (when you don't want it to). I think the reason we didn't have this problem on the old server, was because that script wasn't run under mod_perl (issues sending emails with sendmail, but this time we are using SMTP on the new server so don't have that problem) – Andrew Newby Nov 09 '17 at 10:35
  • @Borodin I'm just doing a test now and then going to do a build to see if it updates the Data.pm file again (incorrectly). If so, thats where the problem lies :) – Andrew Newby Nov 09 '17 at 10:38
  • @Borodin - yup, that was it! Glad that was found. Not how I expected to spend my morning - oh the joys of coding! ;) – Andrew Newby Nov 09 '17 at 10:52