Debugging: Things to work on

Debugging is an area in which I seriously need to improve. That does not just mean fixing bugs, but being able to pinpoint where any code is not behaving as expected (honestly mostly talking about code I have written). "No one writes perfect software, so it's a given that debugging will take up a major portion of your day" - Pragmatic Programmer.

Here are a few techniques and ideas I have learned about debugging.

Make the bug reproducible

This means that I should be able to reproduce this bug with a single command. It shouldn't be required that I take 15 steps clicking on specific things in a certain order to reproduce this bug. That just takes way too much time, especially when testing to see if your solution fixed the problem.

One approach would be to write a test for this particular bug. I am currently working a lot in cypress, so I could write a test case to reproduce this bug and simply run the test when I believe I have a solution.

Be Familiar with moving up and down the Call Stack

This is straightforward. Make sure you are familiar with a call stack and how to navigate your way around. You should know the difference between "step over", "step in" and "step out". The debugger may look different depending on which technology you are using, but the concepts are the same.

Binary Chop

I love this idea. The concept is the exact same as 'binary search'. When trying to figure out WHERE our code goes wrong, we can use a binary chop approach. Simply pick a function call that lies about halfway in your code execution and check your values. If they are expected, you know the bug is in the second half of the code (otherwise in the first half). Repeat with the smaller sections and you are bound to find where the bug is much faster.

I love how this can be applied to so many things outside of finding a value in a sorted array. This concept has applications in all aspects of life.

Logging/Tracing

Logging and tracing are extremely useful when working with concurrent processes, real-time systems, and event-based applications. I like to think about these as race conditions, and logging can help you see which functions are being called in what order. Might be the source of your bug!

Rubber Duck

"Now Harry, tell me. What exactly is the function of a rubber duck?" -Arthur Weasley

This is one that I often overlook. And that is a big loss. I cannot count how many times I have had an issue with some code, started typing out a slack message to my co-worker to describe the problem, and have a possible solution come to me. Simply talking through the problem and leaving your assumptions behind lets you see things more clearly. Often the root of the error jumps right out at you!

Why wasn't this caught earlier?

When fixing a bug, we should always ask ourselves, "why wasn't this caught earlier?" Do we not have tests covering this edge case? Are we not checking for input validation?

Working in cypress for the past few months has definitely forced me to care about this more than I used to. When bugs come in and our tests are "working" (which right now they aren't lol), there is obviously a gap and a missing test case.

Moving forward, once the cypress tests are working and we have good coverage, we need to be asking ourselves this question every time a bug comes in. Potentially could make it mandatory to write a test case for every bug that comes in before making the PR.