"Stephen Clouse" <[EMAIL PROTECTED]> wrote:
> Under [mod_perl 2 and perl 5.10 on Fedora 9] I am getting some of the
> most bizarre and insidious perl core errors I've ever seen in my 15
> years of using perl.
>
> Attempt to free unreferenced scalar: SV 0xbd266be4, Perl interpreter:
> 0xba01c410 at /usr/lib/perl5/vendor_perl/5.10.0/HTML/Mason/Component.pm 
> line
> 147.
> panic: attempt to copy value 20 to a freed scalar bd49dffc
> Use of freed value in iteration
> panic: free from wrong pool
>
> Not to mention countless application errors involving dereferencing.

Dereferencing demons, eh?  Your error rang a bell with me.  But it wasn't 
until I saw List/Util/Util.so in your follow-up post that I remembered, 
List::Util did that same scary crashing thing to me a while back while I 
was debugging krang (which is mod_perl 1.3x-based).

It boiled down to the (IMO) senseless and unnecessary use of weak 
referrences somewhere deep in the dark bowels of the Scalar-List-Utils 
package.  I'd read somewhere that weak references were not all that stable 
in certain recent versions of perl, so when I saw all the weakening being 
done in there (and all the XS bugs the module has had to fix, in its change 
log:

  http://search.cpan.org/src/GBARR/Scalar-List-Utils-1.19/Changes

At the time, upgrading the module to the latest release didn't stop my big 
scary memory reference errors.  So I read through the code that used the 
module and was astonished at why the module was being used: the *one* line 
of code in the entire module that I was troubleshooting that *depended* on 
List::Util was a single, simple call to its exported method: first()

What does first() do?  It invokes kilobytes of fast, compiled XS code to 
...huh?  Return to me the first element in a list I pass to it that returns 
true for a code block I pass to it?  Yup.  Like this:

  # from the POD doco at
  # 
http://search.cpan.org/~gbarr/Scalar-List-Utils-1.19/lib/List/Util.pm#DESCRIPTION

  $foo = first { defined($_) } @list;  # first defined value in @list


Who needs to install a CPAN module to do that?  I personally would have 
written it as:

  $foo = (grep defined, @list)[0];  # first defined value in @list


But thats kind of non-obvious to the programmer who finds it later (if they 
dont read the comment, that is).  You could also simply replace "first" 
with "grep" (and a pair of parens) and get the same effect:

  ($foo) = grep { defined($_) } @list;  # first defined value in @list

(at the cost of one extra byte and some wasted cpu cycles if the compiler 
doesn't notice that the lvalue is a list of length one, and lets grep 
process the whole list anyway, even after it finds and assigns a defined 
element in there).

IMO, even this would be better than loading List::Utils and calling 
first():

  my $foo;
  for (@list) {
    next unless defined($_);
    $foo = $_;
    last;
 }

So I fixed my bug by writing a line or two of perl to in order to remove 
one call to the List::Util module's first() function.


> My problem is that I don't even know where or how to start tracing or
> debugging such an issue to determine precisely what is scribbling on 
> perl's
> memory.

Starting from your error message (line 147 of HTML::Mason::Component) it 
appears HTML::Mason is calling a "dynamic method" method (one named in a 
variable).  No help there.  Okay, what else is HTML::Mason::Component 
using? What libraries has it loaded? Is List::Utils being used?

This looked suspicious to me:

  use HTML::Mason::Tools qw(absolute_comp_path can_weaken);

Just because you "can_weaken" a reference, does that mean you should?  Sure 
enough HTML::Mason::Tools loads Scalar::Util apparently to do some 
reference weakening.

I'd check my Mason component for use of the functions that the 
Scalar-List-Utils modules provide:

List::Util

 first max maxstr min minstr reduce shuffle sum

Scalar::Util

  blessed dualvar isweak readonly refaddr reftype
  tainted weaken isvstring looks_like_number set_prototype

And see if rewriting these in pure perl helps.  Also, if it does, but would 
require changing code that you'd rather not monkey with, it looks like 
there is a pure-perl version of the module that can be installed by passing 
a -pm option to Makefile.PL:

  perl Makefile.PL -pm
  make
  make test
  make install

Anyway, I hope somehow, some of this helps!

-dave 



Reply via email to