I am using Net::LDAP; from within a module I didn't write myself, and
get the following error at exit (everything working otherwise fine):
(in cleanup) Can't call method "FETCH" on an undefined value at
/usr/lib/perl5/vendor_perl/5.8.5/Net/LDAP.pm line 244 during global
destruction.
Is this a known problem, an error in my usage of the module, or in the
intermediate module?
Are there hints for me to debug this?
The version of LDAP.pm I use is:
$VERSION = "0.31";
$LDAP_VERSION = 3; # default LDAP protocol version
The version of perl: v5.8.5 built for i386-linux-thread-multi
I hope I am not misuing this list with this question.
Thanks!
Marc
On 2/21/07, Marc Girod <marc....@gmail.com> wrote:
...
> The version of LDAP.pm I use is:
I downloaded and installed perl-ldap-0.34 (without at least some of
the possible optional modules: Authen::SASL, GSSAPI, IO::Socket::SSL ,
XML::SAX::Writer.
All the tests were successful (10 skipped).
This didn't affect the behaviour I described, apart for the line
number, and the path ('site' instead of 'vendor'):
(in cleanup) Can't call method "FETCH" on an undefined value at
/usr/lib/perl5/site_perl/5.8.5/Net/LDAP.pm line 266 during global
destruction.
Also, I thought I could provide bits of the package code I use:
use strict;
use warnings;
use Carp;
use Net::LDAP;
sub new {
my $class = shift @_;
my $self = {};
$self->{ldap} = Net::LDAP->new('amereast-dc2.ionaglobal.com');
my $msg = $self->{ldap}->bind(version => 3);
if ($msg->code != 0) {
carp "LDAP bind failed: $msg->error_text";
return undef;
}
bless $self, $class;
return $self;
}
sub DESTROY {
my $self = shift @_;
$self->{ldap}->unbind if ($self->{ldap});
}
Marc
> (in cleanup) Can't call method "FETCH" on an undefined value at
> /usr/lib/perl5/site_perl/5.8.5/Net/LDAP.pm line 266 during global
> destruction.
>
> Also, I thought I could provide bits of the package code I use:
> sub DESTROY {
> my $self = shift @_;
> $self->{ldap}->unbind if ($self->{ldap});
> }
That is the source of your problem.
During Global destruction there is no defined order in which perl will
call DESTROY on objects.
Your call to unbind eventually causes a call to ->debug. Net::LDAP uses a
tied HASH to avoid reference loops. What seems to have happened is that
the internal object of the tied hash has already been freed, so when perl
attempts to call FETCH on the internal object you get this error.
The only safe way to solve this is to ensure that all your objects are
destroyed before global destruction.
Graham.
On 2/21/07, Graham Barr <gb...@pobox.com> wrote:
> The only safe way to solve this is to ensure that all your objects are
> destroyed before global destruction.
I hear what you say, and I believe I understand it.
However, my attempt fails. In my user script, I added in the end:
$ldap->DESTROY;
print "DBG: end of the script\n";
[I have in the beginning the obvious:
my $ldap = IonaLDAP->new;
]
I assumed this would be run 'before global destruction'.
However, as I run this, I get:
$ ./chkprop-cron
DBG: end of the script
(in cleanup) Can't call method "FETCH" on an undefined value at
/usr/lib/perl5/site_perl/5.8.5/Net/LDAP.pm line 266 during global
destruction.
Is it thus called anyway a second time?
Thanks for your time and attention!
Marc
On 2/22/07, Marc Girod <marc....@gmail.com> wrote:
> Is it thus called anyway a second time?
Er... I did now the following, which got rid of the problem/symptom:
$ldap->DESTROY;
$ldap = 0;
Is it brutal?
Too brutal?
Marc
Thanks again for your reply...
On 2/23/07, Graham Barr <gb...@pobox.com> wrote:
> You should never call DESTROY directly.
I hear you, but do you have a pointer for me at documentation
explaining why this is wrong, what it may lead to etc.?
Preferably to perl man pages...
[ Slightly worried about a forthcoming rtfm hit on the head ]
> Calling
>
> $ldap->disconnect;
>
> should be enough
The problem with that is that 'disconnect' is a function of Net::LDAP,
which is not exposed by the intermediate package I use, and thus,
following your advice leads to:
svn> ./utils/chkprop-cron
Can't locate object method "disconnect" via package "IonaLDAP" at
./utils/chkprop-cron line 199.
(in cleanup) Can't call method "FETCH" on an undefined value at
/usr/lib/perl5/site_perl/5.8.5/Net/LDAP.pm line 266 during global
destruction.
Is it to say I ought to modify the module?
Would you please advise me how?
I'd say it packages for me a useful bunch of clues on getting specific
info from our company ldap database...
Marc
> Hello Graham,
>
> Thanks again for your reply...
>
> On 2/23/07, Graham Barr <gb...@pobox.com> wrote:
>
>> You should never call DESTROY directly.
>
> I hear you, but do you have a pointer for me at documentation
> explaining why this is wrong, what it may lead to etc.?
> Preferably to perl man pages...
> [ Slightly worried about a forthcoming rtfm hit on the head ]
As it states in
http://search.cpan.org/~nwclark/perl-5.8.8/pod/perlobj.pod#Destructors__
Explicitly calling DESTROY is also possible, but is usually never
needed
But calling DESTROY explicitly is NOT destroying the object. It is
called
DESTROY because perl will call it when the object is destroyed. Not
all objects even define a DESTROY method.
>> Calling
>>
>> $ldap->disconnect;
>>
>> should be enough
>
> The problem with that is that 'disconnect' is a function of Net::LDAP,
> which is not exposed by the intermediate package I use, and thus,
> following your advice leads to:
>
> svn> ./utils/chkprop-cron
> Can't locate object method "disconnect" via package "IonaLDAP" at
> ./utils/chkprop-cron line 199.
> (in cleanup) Can't call method "FETCH" on an undefined value at
> /usr/lib/perl5/site_perl/5.8.5/Net/LDAP.pm line 266 during global
> destruction.
Ah, I was assuming that $ldap in your script you were calling DESTROY on
was a Net::LDAP object.
So whatever IonaLDAP is it should provide a way to disconnect from
the server.
Or at least not call unbind in its DESTROY method. It is usually not
required
anyway as the socket connection will get closed anyway.
Graham.
I'll both test the change, and negociate with the original author of
IonaLDAP.pm, to check he had no special reason to do that.
Marc