Monday, 19 February 2018

Bring Out Your Defects



Debugging is a universal pain known to all developers and software engineers, despite our best efforts to improve and get it right this time its an inevitable outcome given the complexity of writing code at scale.

It can have many stages from denial and anger to acceptance and ultimate resolution.

Given that, engaging in debugging is unavoidable and its clear that we need a strategy for effective debugging. For many this is built up from the scars and wounds of previous battles with a code base, it will also be influenced by the particular area of development that you operate.

What is presented here is far from a full proof strategy that will always enable you to root out defects quickly and painlessly, but any tips and tricks can be useful to have in your armoury when you go into battle.

Don't Panic

First and foremost don't beat yourself up when a bug is uncovered, writing bug free code is virtually impossible once your code base grows beyond a certain size. Developers and development teams should be judged on how they deal with defects not simply whether or not they exist.

The majority of defects will be simple mistakes, when a defect first appears we can often assume it has a complicated root cause. Instead, accept your human fallibility and expect to find out that you've just had a momentary failing of intelligence.

The first action should be to make sure that you understand the manifestation of the defect and you have a path to reproduce, without that not only will you struggle to find the cause you will also have little confidence that a potential fix is effective.

Once you start attempting to find a fix try to reduce the number of variables in play, change one thing at a time and have a heightened sense of when you've reached a point where your not sure of the logic of what your trying anymore. 

When it works you need to be able to explain why.

For a complex defect you will more than likely have several false starts, reset your approach whenever your in a situation where even if something works you won't be sure how your got there.

Use Your Tests

Unit tests are invaluable in proving your code works after you make a change, they also have equal value in demonstrating how your code isn't working.

Well written tests act as documentation for how things are supposed to work as well as providing an effective test harness to enable you to exercise the problematic piece of code.

When a defect has been identified, assuming you don't already have a failing test, construct a test that will expose the problem and use this as your primary means to attack the issue.

Not only will this help you analyse and ultimately fix the problem it will ensure that any potential future regression can be identified quickly and stopped.

The tests you add will also act as documentation for any developer who may touch that area of code in the future of the potential problems that can be introduced.

Write Debuggable Code

The majority of us tend to worry about optimisation far too early in the life of a code base, this early over optimisation can often come at the expense if readability and simplicity.

While there are always caveats to any sweeping statement in the majority of cases a lack of maintainability is likely to hurt your team much sooner than a lack of performance. Indeed one is likely to have a linkage to the other as successive developers make sub-optimal changes to a code base they don't understand.

Debuggable code exhibits a clear statement of intent along with a clear approach.

Overreaching for conciseness or performance can act to hide intricacies that will hamper efforts to debug and patch.

Comments are no savour for this situation, while they have a place they have no direct link to the code they are associated with and can easily cause more confusion than insight.

If you are unfortunate enough to have to apply a fix to code like this then consider refactoring to increase maintainability for the next developer to come along. Code that has previously had defects, especially ones that have been difficult to solve, is probably more likely to have them again and each subsequent patch is only likely to make the situation worse.

Being an effective debugger is one of the skills that comes with experience, the scars that can come from a debugging battle are a rite of passage for a developer. Whilst it can portray elements of an art over a science an acceptance of it being part of the development cycle and approaching it in an analytical manner can provide an effective framework for gaining that experience.   

No comments:

Post a Comment