On Oct 3, 2008, at 7:35 AM, Peter Daum wrote:
Peter Daum wrote:
I recently upgraded a system (as far as perl is concerned from
5.8.8 to 5.10.0). Afterwards I ran into a mysterious problem. I
could eventually
> find a workaround, but still don't really understand, what is
going on.
After the upgrade, a perl program wouldn't run anymore - it crashed
with a message:"*** glibc detected *** /usr/bin/perl: double free
or corruption (fasttop): ..." and a memory map suggesting some
problem on the heap.
The crash can be reproduced by the following code:
use Net::LDAP;
my $self=Net::LDAP->new("127.0.0.1");
($self->{prog_name}= $0) =~ s|^.*/([^/]+)$|$1|;
# when I put an intermediate variable into the statement:
$self->{prog_name}= (my $_p= $0) =~ s|^.*/([^/]+)$|$1|;
the program works again.
Technically, my problem is solved, but maybe somebody here can shed
some light on some questions:
> - I tried to run the program under the debugger hoping to find,
where
exactly the error occurs - unfortunately the same program
suddenly worked
> just fine, so I ended up putting print statements into the
code until I
> eventually found the problematic line. Why can't the crash be
reproduced
> under the debugger? Would there be an easier way to find the
problem?
- Generally, I still don't understand what's wrong with the
original program code.I didn't try it but I don't think it is
anything specific to Net::LDAP. However, when $self is just some
hash reverence ("my $self={}"),
> the code also works without any problem.
Actually, it seems like the problem is indeed specific to Net::LDAP;
furthermore,
the crash only occurs, if there is a LDAP server running at the
specified address.
I still would love to know where exactly the problem is.
Is there a bug somewhere in Perl or in Net::LDAP?
Am I doing something wrong? (well, some might argue that it's a bad to
rely on Net::LDAP::new returning a hash reference and isn't using a
key named
"prog_name" ...)
Net::LDAP has reference loops internally. To ensure that memory is not
leaked it plays tricks with tie so that the ref that the app holds is
not part of the loop and the loop can manually be broken when needed.
In your first statement
($self->{prog_name}= $0) =~ s|^.*/([^/]+)$|$1|;
you are calling s/// on the hash element. In the second
$self->{prog_name}= (my $_p= $0) =~ s|^.*/([^/]+)$|$1|;
you are just setting the hash element, actually to the value "1" not
the prog name. You probably want
($self->{prog_name}) = $0 =~ m|([^/]+)$|;
Anyway, I suspect the issue is todo with calling s/// on the element
of a tied hash.
See if this reproduces the issue.
{
package Foo;
use Tie::Hash;
use base qw(Tie::StdHash);
sub new {
my $proto = shift;
my $inner = bless {};
my %outer;
tie %outer, __PACKAGE__, $inner;
bless \%outer;
}
}
$self = Foo->new;
($self->{prog_name} = $0) =~ s|^.*/([^/]+)$|$1|;
Graham.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/