Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Monday April 27, 2009
02:49 PM

Quick-finding a leak

[ #38881 ]

Symptom:

Use of uninitialized value in subroutine entry at /home/y/lib/perl5/site_perl/5.8/Log/Log4perl.pm line 132 during global destruction.

I got this in the destruction in one of my objects when it tried to log its destruction.

Checking the Log4perl FAQ shows me that this means I have a circular reference somewhere in my code; Log4perl's getting called during global destruction, when the Log4perl structures have already been destroyed themselves.

Trying the easy and obvious thing first, I used Devel::Cycle and tried running it on the object that was being destroyed ... except that wasn't the object with the leak - it was simply indicating that something pointing to it had a problem. So how was I going to locate it? I tried using Devel::Leak, but I got a huge SV dump that looked like I would have to print out and then connect things together with arrows by hand.

I'm far too lazy to do that, so I thought about it a while. I had a small test case that duplicated the problem; how could I zero in on the point in the test case where I created the circular reference? The light came on: the debugger! I knew that Log4perl would throw its error during global destruction, so all I had to do was run through the code in the debugger, continuing to each point where I created more objects ... and then simply do a q to exit the program and trigger global destruction at whatever point I liked. When I got to a line that caused Log4perl to throw the error, I'd have the piece of code had created the circular reference.

In just a few minutes, I was able to zero in on the method that was creating the circular reference, and in just a minute more, to find exactly the piece of code that had created the problem. Toss in a weaken(), problem solved. I could have done this by editing the code and moving a exit through it, but this was simple and easy, plus I didn't have to change the code to find the problem.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.