Quick-finding a leak

pemungkah on 2009-04-27T19:49:05

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.


There's also...

Alias on 2009-04-28T01:07:56

Devel::Leak::Object