DEV Community

charliekroon
charliekroon

Posted on

A step-by-step guide on debugging

When I started working as a Software Engineer 2.5 years ago, bugs were intimidating to me. I did not know where or how to start debugging and it felt like an enormous task I would never be able to tackle alone.

I often wished for a step-by-step guide on how to approach the debugging process. I never found one, so I decided to create my own.

Step 1
Slow down and be methodical
When debugging, it’s of great importance that you work as methodically and cleanly as you possibly can. Change one thing at a time, write down the steps you’re taking, and note down your thoughts. By working as clean and controlled as possible, you avoid digging yourself into a hole of bugs, and it’s less likely that you’ll introduce a new bug by making an unnecessary change.

Step 2
Investigate
To solve a bug, you need to understand it. To understand the bug, you need to ask yourself a lot of questions, such as:

  • Is the code being called?
  • Am I missing a file?
  • Is this route correct?
  • What does that parameter do?
  • What is the value of that variable?
  • Is the function in the server, in the client, or, — when debugging a test — in the test?
  • Did I introduce the bug with my latest change, or was it there all along?
  • Is that function doing what I think it’s doing?
  • Am I working on the correct file?
  • Which function is returning that incorrect value?
  • What is the error message actually telling me?
  • Is this happening in my code or in the library that I am using?
  • Can I write a test to reproduce the bug?

Step 3
Trust, but verify
Oftentimes I make assumptions that I wholeheartedly believe and don’t even think of questioning. I tell myself things like: ‘I wrote the variable name correctly’, ‘the bug was introduced by the last change I made’ or ‘this function does X’. Hours go by until I figure out that that variable name had a typo, that the bug was always there, but my last change had brought it to the surface, or that the function was, in fact, not doing X. You can trust your assumptions, but verify them.

Step 4
Set a timer and ask for help
The difference between working in a team with other engineers, and working on your personal projects, is that there is no unlimited amount of time to spend on bugs. When you put your name on a ticket in the sprint, you basically say: ‘hey, I take responsibility for this issue. I’ll make sure it’s finished.’ Taking that responsibility doesn’t mean that you need to do everything alone. It means you’ll finish the issue and make it ready to be shipped to production in a timely manner. Sometimes that means that you need the expertise from someone else.

A way to find the balance between asking immediately for help and trying to fix an issue alone for days is to set a timer for an hour. If the bug is still not fixed by then, you can message your coworkers.

Here is a template of the message you can send:

  • This is what I am trying to do
  • I did … and I expected … to happen, but instead … happened
  • I have tried …, … and … to fix it, but …
  • I think the reason why this is happening is that…
  • This seems to be possible/impossible, because …

Step 5
Take a break
Investigating a bug requires a lot of focus. The longer you work on a bug, the more likely it is that you’re missing things. Take a break, go outside, cook, clean the kitchen, take a shower, work out, hang out with your friends, take a nap, watch The Office. When you come back to your bug, chances are that everything is a lot clearer.

There is always a logical reason behind a bug. Sure, some bugs take a bit more time to figure out, but nothing is ever unexplainable and thus solvable. The nastier the bug is, the better of an engineer you’ll become, I promise.

Top comments (1)

Collapse
 
wadecodez profile image
Wade Zimmerman

This article is about problem solving than debugging.

It's so much faster to read the stack trace and set a break point than to make educated guesses. With a proper debugger, you can investigate all previous and future calls, one at a time, and see when the program throws an exception, or why/why not a value is being changed.

Otherwise, it's super easy to make assumptions which are not entirely true.