An introduction to troubleshooting for software developers
The best software developers don’t just write code, they also debug it. Whether you wrote your current codebase or inherited it, this introduction provides a framework for best practices.
The Myth of Bug-Free Software
All software has bugs. This is a fact that anyone who has worked in software development knows. It would be extremely expensive to try to eliminate every minor flaw in an application of any complexity. Never mind that software testing ultimately only proves the existence of problems, not their absence. That said, there are certain types of software flaws or bugs that need to be fixed.
SEE: Recruitment Kit: Back-end Developer (TechRepublic Premium)
The usual suspects
There are a number of factors that contribute to soft errors. Here are some of the most common:
- Ambiguity in expected behavior
- External subsystems or components
- Insufficient tests and delays
- Programming errors
Whatever the culprit, at some point in your career, either you will decide, or someone will decide for you, that a flaw needs to be corrected. How this determination is made varies, but it is usually a combination of behavior, actions, loss tolerance, and client minimization. Most competent software developers can fix a problem once the cause has been discovered. The process of finding the cause is called troubleshooting or debugging.
Troubleshooting vs Debugging
Simply put, debugging is a subset of troubleshooting. You can troubleshoot without debugging, but you can’t debug without troubleshooting. If that sounds confusing, that’s because it is.
Troubleshooting tends to occur at a higher level of abstraction than debugging and applies to many system components. It is the process of analyzing the component or components of a system that are causing problems. Troubleshooting can be applied to any system and does not imply that the problem will be fixed, but rather the focus is on finding and understanding the root cause.
Debugging, on the other hand, is specific to computer code. As a developer, if you are tasked with debugging a software module, you are asked to find the instructions causing the unwanted behavior and fix it, all within the same session when possible.
The first step in troubleshooting and debugging unwanted behavior in software is to ensure that the problem is properly documented. This will ensure that all parties involved have the same understanding and will help inform later stages of the process. At a minimum, a properly documented bug covers the following:
- The description
- Steps to reproduce
- Reproduction rate
- Expected results
- Current results
- Environment and version
Estimated bug fixes
As a developer, you will often be asked to estimate how long it will take to find and fix a bug. Unfortunately, there is no right answer. A recommended practice is to limit your initial efforts to 4 hours or half a day. During this first session, you should focus on uncovering a few key nuggets of information.
- Can you reproduce the problem?
- Do you know the root cause?
- Have you narrowed it down to a domain or a component?
If you are able to find and fix the problem within the initial time frame, congratulations. If not, it’s probably appropriate to go ahead and provide some sort of t-shirt size estimate based on your initial debugging effort to stakeholders. Below are some general tips, but be aware that your mileage may vary:
- Small: Requires 4-8 hours to fix the issue.
- Medium: Requires 2-3 days to resolve.
- Large: May take a week or more to resolve.
- X-Large: Will require additional team members and/or planning to resolve.
At this point, you might be wondering why provide any kind of estimate if estimating bug fixes is such an inexact science. The truth is, it’s about providing transparency both to help manage stakeholder expectations and to provide product owners with options when or if it becomes clear to do nothing until the patch is available is not an option. Albert Einstein is credited with once saying, “We cannot solve our problems with the same level of thought that created them.”
Proven Debugging Techniques
Every modern IDE has a plethora of debugging options. These are usually specific to your programming environment and are meant to make your life as a developer easier. That said, don’t overlook the basics.
Print things: many things
Logging remains one of the most effective ways to troubleshoot a problem. You’d be amazed how many times logging reveals that the code you’ve been troubleshooting isn’t even called.
Read the error message
Googling an error is a great way to see how those before you may have solved something, but be sure to take the time to read the error message thoroughly first. Most modern languages and frameworks will give you a good idea of the nature of the error, and many suggest fixes specific to your situation at the time the error occurred.
Start with code that already works
Developers use source code control for a reason. Whenever you can roll back to a working version and then differentiate the codebases, you will be able to reduce the offending section of code much faster. Even if the error was only recently discovered, you can often go back several versions and then apply updates one by one until the unwanted behavior reappears to better understand the problem.
Run your code every time you make a change
Sounds like a pain, but seriously, running the code and checking for behavior changes as often as possible can save you backtracking through your troubleshooting steps.
divide and conquer
Often overlooked, simply commenting out the code until the problem disappears can be a quick and dirty way to unearth the offending instructions.
Rubber ducky debugging
Sometimes troubleshooting software becomes a team sport and requires thinking outside the box. One such technique is known as “rubber ducky debugging”. It’s based on the principle that sometimes when troubleshooting software, we need to slow down to go faster. The steps for debugging the rubber ducky are described below.
SEE: Recruitment Kit: Python Developer (TechRepublic Premium)
- Begging, borrowing, stealing, buying, making or otherwise obtaining a rubber ducky (bathtub variety).
- Place said rubber duck on your desk and let him know you’re just going to go over some code with him – if that’s okay with you.
- Tell the duck what your code is supposed to do, then go into detail and explain your code line by line.
- At some point, you’ll explain to the duck what your code does and realize that’s not actually what your code does. The duck will look at you smugly.
- Thank the duck for his time and fix the code!
Don’t panic. Like most things we do in life, troubleshooting software gets easier with experience and practice. The key is to be transparent with stakeholders throughout the process, to keep your approach organized and methodical, and to not be afraid to ask fellow programmers for help.