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

I was modifying one of our processes today and I came across some bizarre behavior. Essentially, the process reads in a flat configuration file which contains data like
stored_proc_list => [ 'sproc1', 'sproc2', 'sproc3' ] update_stats_xref => { 'sproc2' => 'update_table2' } logfile => somefile.txt
and converts them into Perl variables (array ref, hash ref, and scalar respectively) using an eval statement. When I tried to update the code to allow for scalar references (which would immediately get converted into a scalar), it started to core dump on me. I have included the offensive code below, stripped down to what appears to be its barest elements. Essentially I have a string, which gets turned into a Scalar reference when I eval it, which I then try to assign back into the same value. If I do a Scalar assignment, it blows up. If I do a list assignment, it works just fine.

I was hoping that someone out there can explain this behavior to me. I have already found a working solution, but I was curious as to why it works (or doesn't) the way it works. Note: I have tried this on both NT 4.0 (which I where I do most of my development :< ) and on AIX.
my $temp_value = q(\'/Path/to/log.txt'); my $value = eval $temp_value; # This one results in no value for $value and coredumps $value = $$value; print "New \$value = $value\n"; # This one does what I want it to do ( $value ) = ( $$value ); print "New \$value = $value\n";
Thanks for any insight,
Mike
mppennucci@delinvest.com

Replies are listed 'Best First'.
Re: Bizarre References Question
by steves (Curate) on Feb 14, 2002 at 20:22 UTC

    Interestingly, this does work:

    use strict; my $temp_value = q(\'/Path/to/log.txt'); print "1> $temp_value\n"; my $value = eval $temp_value; print "2> $value\n"; print "3> $$value\n"; my $foo = $$value; print "4> $foo\n"; $value = $foo; print "5> $value\n";

    So assigning to an intermediate scalar works. That seems to indicate a problem in the assignment statement. But that looks legal to me ...

(Zaxo) Re: Bizarre References Question
by Zaxo (Archbishop) on Feb 15, 2002 at 04:46 UTC

    This appears to be a bug in perl. It looks like the memory where the anonymous string lives is released before the assignment is done, resulting in an invalid memory access. Segfault.

    Here's a workaround that relies on increasing the refcount so that underlying memory is not released:

    my $temp_value = q(\'/Path/to/log.txt'); my $value = eval $temp_value; { my $foo = $value; $value = $$value; }
    I'm looking for how to fix perl, but I invite anyone who knows the code better take this and run with it.

    After Compline,
    Zaxo

Re: Bizarre References Question
by blakem (Monsignor) on Feb 14, 2002 at 20:22 UTC
    Oddly enough, changing the LHS from $value to $value2 avoids the coredump on my linux machine... *shrug*
    # This one used to coredump, but doesn't anymore... my $value2 = $$value; # was $value = $$value print "New \$value2 = $value2\n";

    -Blake

Re (tilly) 1: Bizarre References Question
by tilly (Archbishop) on Feb 15, 2002 at 03:27 UTC
    If you use strict.pm you will get slightly more information under 5.6. In 5.005 you will not, though you get a more bizarre error if you replace the print with print "$$var";

    The key point that causes the problem is likely that the assignment is in the process of wiping out $var as you are trying to also dereference it. Depending on the exact order of actions, you can easily get into nasty little boundary conditions.

    Perl should still not segfault though...

Re: Bizarre References Question
by abaxaba (Hermit) on Feb 14, 2002 at 20:13 UTC
    I cannot adequately comment on the coredump. I do think the $value = $$value causes issue -- in my mind, you're saying that \$value = $value; Or, pointer to memory location of $value = content of memory location of $value. Nevermind that $value is a scalar, not a scalar ref, to begin with. What I don't really understand is the ($value) = ($$value) bit. Why using list syntax lets this work is for others more experienced than I to answer. But hey, whatever works...

    I would, however, suggest one thing. As opposed to reading the text, then using eval to "perlfy" it, why not do something like this:
    Change your current "config.txt" to "config.pl", and rewrite thusly:
    $stored_proc_list = [(qw(sproc1 sproc2 sproc3))]; $update_stats_xref = {sproc2=>"update_table2"}; $logfile = "somefile.txt"; 1; #Return true val

    Then just require it. All of your vars then get populated without using the eval.

Re: Bizarre References Question
by particle (Vicar) on Feb 15, 2002 at 04:06 UTC
    it's been said, before... it looks like a bug. i'm running 5.6.1, and i get segfaults.

    correct me if i'm wrong, but it looks like it bombs out when trying to reassign the SCALAR slot in the typeglob in scalar context using the = assignment operator. all is good if the left hand side is in list context.

    boy, that was a mouthful.

    ~Particle

Re: Bizarre References Question
by Anonymous Monk on Feb 15, 2002 at 01:32 UTC
    #this works
    $value = \'xyzzy'; $value = $value2 = $$value; #this coredumps $value = \'xyzzy'; $value = $$value; #looks like a bug to me.
      Weird.

      Neither core dump for me.

      Only the eval version does that here.

      This is perl, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2001, Larry Wall Binary build 629 provided by ActiveState Tool Corp. http://www.ActiveS +tate.com Built 12:27:04 Aug 20 2001

      Yves / DeMerphq
      --
      When to use Prototypes?

Re: Bizarre References Question
by demerphq (Chancellor) on Feb 15, 2002 at 17:19 UTC
    While I cant comment on the core dump, or any of the other weirdness discussed here, I have encountered problems when using \'scalar' with Data::Dumper and Data::Dump. For instance some dumps from either can crash on eval because of this ("Cant alter constant value..."). However there is a simple trick, replace it with the following
    my $x=\do{my $x="string"};
    Problem goes away... Dunno about your situation tho'.

    Update it appears Zaxo has worked this out, but the above code is a viable workaround. Better imo than ($value)=($$value) if only because the resultant can be assigned to.

    Yves / DeMerphq
    --
    When to use Prototypes?