The Subtle Art of Debugging21 Jan 2019
We are human and we make mistakes. A software developer’s biggest enemy is error, a.k.a bugs. No one wants to make bugs, but it is inevitable. If someone writes code quickly; or if someone writes well-structured code, does that mean they are a good developer? To be good, you need to know how to debug your code or someone else's code.
So if we can't avoid creating bugs, what should we do?
We should detect and remove bugs. This sounds quite simple so far.
We need to ask - where are those bugs are coming from? Can we not have them at all? We usually have them because we are working as a team and we often touch each other's code. When we do that, there is a higher chance of creating bugs because a different developer may not consider all the edge cases when making their changes.
What is debugging then?
"Debugging is the process of detecting and removing of existing and potential errors (also called ‘bugs’) in a software code that can cause it to behave unexpectedly or crash. To prevent incorrect operation of a software or system, debugging is used to find and resolve bugs or defects. When various subsystems or modules are tightly coupled, debugging becomes harder as any change in one module may cause more bugs to appear in another. Sometimes it takes more time to debug a program than to code it." (Source)
Here are some basic steps of debugging:
- Replicate the problem and know how to reproduce the problem. You need to know who your enemy is first.
- Investigate the code and find where it breaks or looks suspicious.
- Put a debugger into your code
- Re-run your program and see if it hits your debugger
- If it does, then check the inputs and logic in your code. If it does not hit your debugger, then you are looking in the wrong place. Go back to step 2 and try again. Worst case scenario, after several attempts it does not hit your debugger and you have no idea where it is, try to put the debugger everywhere.
- When you are in the "debugger, play around with the code. Print out some values and check if they are all correct. Test with some functions to check whether they are returning correct values or not.
- If you find which part is causing the problem, trace the code back to identify where the problem begins. Implement a potential fix and then forward analyse the code.
- After making changes, make sure you check related code and test that it has not broken other things.
To all the developers in the world, I highly recommend that the debugging tools mentioned should not only be used to fix the bugs, but also be part of your normal development process. It is a good process to reduce the chance of creating potential bugs. If you use the debugger while you are developing, you will not need to come back (hopefully) and debug your code again (ideally).
What is better than fixing a bug? It's not creating bugs at all!
One of the options that we put all our efforts into is writing readable and maintainable code. So that when you leave a project and a new person joins, they can understand what your code does when they try to solve a problem.
Another option is to write test code that validates that your code is working as expected. This methodology is known as "test driven development". This is a powerful arpproach and is something we do at Sentia. Test driven development helps us to prevent generating bugs when changing existing code, reducing the amount of time executing manual testing.
However, there are differences between debugging and testing. Testing is the act of detecting and finding errors in the code base. Whereas, debugging begins after we have found a bug. Since every issue is different, there are many techniques to approach a problem and in order to solve it. Debugging requires a lot of experience, knowledge, skills, and expertise in your programming language. I would say software development is 20% coding and 80% debugging.
To be a good developer, you need to know what debugging tools are available in your programming language. It is important to know how to use it, familiarise yourself with it and use it as much as you can.
If you know the enemy (bugs) and know yourself (debugging tools), you need not fear the result of a hundred errors.