Powered by a whole foods plant based diet, a well dressed penguin and an over-active imagination

Debugging Perl

or “Looking For The Obvious”

I started my working life in electronics as an apprentice working on communications equipment. I spent a lot of time doing component level diagnosis and repair of communication equipment, everything from two way radio sets to analog and digital microwave bearer equipment. There was one card which we had so many spares for that nobody bothered to repair them until the spares started to run out. At which point I setup a test rack and made a start on a box of 200 or more faulty cards.

I soon knew all the common faults this card had and I had a series of notes on how to pick them- waveform diagrams and voltage measurements. One card had me stumped though, I worked on it on and off for 2 or 3 days. Eventually one of the other technicians stopped by to see how I was doing. I told him about the progress and how I was stuck with this particular card. I showed him what I had checked and the weird waveforms at various points on the circuit board. His response was “Have you checked the power supply?”. I told him that the power supply was fine and to demonstrate I connected the oscilloscope and showed him various waveforms on the board. He asked again if I had checked the boards power supply. I showed him some more wave forms. When he persisted I gave in and checked the power supply only to find that the only fault this board had was a missing fuse! I could easily have spotted the fault with a visual inspection! (The waveforms I could see on the card were coming from the other connected devices in the test rack.) It was a powerful lesson and one I thought I had not forgotten.

Last week I was asked by a colleague to help with a Perl problem. The error message was for a missing module IniConf. I jumped over to CPAN and found the module and becuase it hadn’t been updated since August 2000 I checked the Readme and found that Config::IniFiles is a drop in replacement. I downloaded and installed Config::IniFiles edited the script to call the new module and told my colleague it was all good.

He soon complained again though. The error messages indicated a problem with the script other than the edit I had done. I asked him if it had worked before and he said it had. I jumped in and found 3 missing quoation marks from a section of code. He then recalled having edited that code so I fixed it and gave it back to him and went back to what I was doing. Now it wasn’t producing any parse or compile errors but it was still failing at run time.

The original program was written in 1998 and did not use -w or stict and didn’t check return codes in many places. But it had worked prior to my colleagues edits and I had fixed them. The IniConf initialisation was in a 20 line commented subroutine which did nothing other than

$cfg = Config::IniFiles->new( -file => “/path/configfile.ini” );

so I removed the subroutine and just in case checked again. It was failing on reads from the inifile “Can’t call method “val” on an undefined value”. The section of code which was calling method val was a 16 line commented subroutine which did nothing other than

$val = $cfg->val( ‘Section’, ‘Parameter’ );

I replaced that code as well. It felt good but it didn’t fix the problem. I checked the return value from Config::IniFiles new method. $cfg was not getting set. I then wasted some time insisting that it was the script that was at fault (even though the evidence indicated otherwise) after all I hadn’t found any reason to trust it so far. Eventually I gave in and wrote a 5 line test case which demonstrated the problem. I didn’t believe that Config::IniFiles would be at fault (it had passed its tests when I installed it) but I wasted some more time looking at it any-way. I read the documentation again, the new method “Returns a new configuration object (or “undef” if the configuration file has an error).”

I had had a (brief) look at the ini file and dismissed it because it was pretty simple and it had “worked before”. Time to look again. I deleted all the config file apart from one section and one name value pair. This time it worked. I asked my colleague if he had edited the ini file “Nope I just added a couple of comments”. Great. Delete all the comments. Worked again. Taking a closer look at the comments showed one line starting with a “:” instead of a “;” (which proves that a “#” is a far superior comment character to “;”!).

Going back to the real program with the fixed ini file and it worked. Just to be complete I replaced
$cfg = Config::IniFiles->new( -file => “/path/configfile.ini” );

$cfg_file = Config::IniFiles->new( -file => $ini_file )
|| die “Config::IniFile method new failed\nProbably error in $ini_file\n”;

so that the next poor schmuck is pointed in the right direction. (It would be much better if Config::IniFiles set $! on failure, a bug report/feature request is still outstanding.)

  • use strict and -w (although fixing this 3000 line monster was out of my scope)
  • Always check return codes.
  • If someone edited something find out exactly what and where and check that first.
  • If you are a module author set $! for failures. Update: this is wrong, see here for why.

What “check the bleeding obvious” lessons have you learnt?

Crossposted to