3.5. Debugging

Most of my initial work on Umbrello was debugging the features which had been added since the last stable release but not yet properly tested. Bugs can involve any area of the code and each one requires detective work to find the relevant code, understand it and work out why the error occurs.

One vital tool for debugging is the GNU Debugger, gdb. It allows backtraces which show the exact line where an error occurred and how that method was reached. It can also be used to step through a programme line by line displaying the values of any variables, however I usually find it just as easy to send lines to standard output showing only the variable in which I am interested.

While debugging it is very tempting to refactor the code to remove any duplications. Doing this is a balance between removing excess code and ensuring that you don't create another bug by unknowingly changing the behaviour.

A large number of bugs are crashes caused by using uninitialised variables. Gdb usually tracks these down quite easily but it can then be hard to work out why the variable was not initialised. It typically turns out to be a route through the code which was not anticipated when it was first written. To prevent this it is important that any class initialises its member variables as soon as possible after construction. After fixing this type of bug I usually create or bring up to date an init() method which initialises all the class variables.

A new tool called Valgrind[valgrind] has recently been released to check all reads and writes of memory for use of uninitialised variables, reading/writing after memory has been freed and memory leaks. Valgrind will not catch all memory problems because it can only detect those which occur during a running occurrence of the programme. To find all problems you would have to run the programme through all possible states, a practical impossibility in a code base of this size. So while I was busy detecting user reported bugs, one of the other developers ran Valgrind over Umbrello. It did not pick up any of the reported problems but it did pick up many unreported ones and it is likely that this solved many problems before they were ever noticed.

Many of the errors which have been fixed are interface inconsistencies. Menu items with different names for the same operation, buttons in the wrong order or unclear text. Again, refactoring of code to remove duplications, usually just creating a method of one or two lines, can prevent inconsistencies occurring.