Why is Using the Debugger so Controversial?
It turns out using the debugger is somewhat controversial, who would have thought it?!
Let’s explore why.
Over the past few months I have been working on The Ultimate Guide to Debugging in Go (which is now released!) When I came across this meme which made me laugh so I tweeted about it:
If this is true, this is going to make my course much shorter 😂😂 https://t.co/1TL9gwVxno
— Matt Boyle (@MattJamesBoyle) January 17, 2024
I was really surprised to see some really experienced engineers state that they never use the debugger, have not for years and don’t recommend it to others. Myself and all my colleagues use it regularly. I wanted to understand this a little more, so I made a poll:
I love Go twitter, I learn a bunch every day. Seems debugger usage is contentious.
— Matt Boyle (@MattJamesBoyle) January 17, 2024
Do you generally use the debugger when developing #golang?
I'm specifically interested in code you are familiar with.
787 people voted, and although the majority did use the debugger, a large proportion (37%) did not. A not insignificant portion said they didn’t know how to, but my course will help them ;)
The discussion on this tweet is where things got a little more interesting, with some indicating that if they need to reach for the debugger it’s a sign of a code smell:
That first feeling of needing a debugger is a code smell indicating the need to refactor the control flow and/or how error conditions are being handled/returned back up the stack.
— daved (@daveddev) January 17, 2024
I think there probably is a strong Venn diagram intersection of people who will hastily yell about premature abstraction, rejecting modularity, and highly skilled debuggers.
— Chris James quii.bsky.soc (@quii) January 17, 2024
Where as others shared my view:
I can't live without a debugger. There's nothing faster than just single stepping through some code instead of trying to act all smart and guess what it's doing. If your not using a debugger then your doing printf and wasting your time. Learn to use a debugger.
— Darren Shepherd (@ibuildthecloud) January 17, 2024
dlv is the first tool I reach for when a bug isn't immediately obvious. Also a great way to familiarize yourself with new code.
— Tim Hockin (thockin.yaml) (@thockin) January 18, 2024
My Case for using the Debugger
My case is a simple one and twofold; if you don’t know how to use the debugger, you should learn how. If you then decide you don’t want to use it as it doesn’t suit your workflow, then that’s a great outcome as you learned a new skill and opinion.
For those that already know how to use it, here is why I think you should use it more often.
Some Code is just complex
Even if you implement all the correct patterns, some code can just have a lot going on. After all, our code is meant to represent our business domain, and some domains are complicated! Being able to set conditional breakpoints as you “play” with a codebase is an incredibly powerful way to up-skill.
Evaluate more expressions than you can fit in your head
Follows on from the previous point, computers are really really good at keeping track of things, and we should let them do it for us. If you are interested in a value at a point in time, the debugger can help you here.
Tests are just code; you can make mistakes in tests too
A lot of arguments resolved around the fact that if you are using the debugger, you should just write a test. Tests are code too and can be complex to follow too. I particularly find this in Go where people write some pretty confusing tests with a goal of keeping them in the Table Driven model. Also, sometimes I just straight up make mistakes in my assertions, and using the debugger helps me figure this out.
Not all code bases are perfect
Follows on from the previous point; “just write a test” is not applicable to every code base I have ever worked on without a refactor. That should be the goal, but just understanding how everything works is always the starting point, and the debugger helps here.
(At least for Go) Starting the debugger is fast with little overheard
This isn’t true for all languages, but for Go, starting the debugger is very easy and fast. Most IDEs allow you to get setup with little to no overhead.
Slow things down
Slowing down the pace of code execution using a debugger is a powerful technique that grants you the opportunity to analyze the behavior of their applications in real-time. This deliberate slowdown is not about hindering progress but rather about ensuring a thorough understanding of the code’s flow and logic. By stepping through code line by line, you can observe the state of variables, the execution of conditional statements, and the interaction between different components at a granular level. This approach allows for the identification of subtle bugs and logic errors that might be overlooked during faster, more automated testing processes.
Slowing things down not only enhances the quality of the software but also enriches your comprehension.
Conditional Breakpoints
This functionality is incredibly useful for isolating and diagnosing issues that occur under specific circumstances without having to manually pause the program at every step or sift through irrelevant parts of the code.
This targeted approach makes debugging more efficient, especially in complex systems where issues may only show up under certain conditions or during interactions between various components.
The Debugger is great for local development; but it’s not a replacement for logs, metrics and traces
The debugger is as an invaluable tool for local development, providing developers with the means to interactively step through their code, inspect variables, and understand the flow of execution in real-time. However, it’s crucial to recognize that the debugger’s usefulness is primarily within the confines of local development. When it comes to monitoring and diagnosing issues in production environments, logs, metrics, and traces become invaluable.
Wrapping Up
After the discussion, I did re-consider some of the points raised, and wonder if I am just a worst/slower engineer than those who do not need to use it. However, I was reassured that having to use the debugger is not a metric for skill when I discovered this interview with Lex Friedman and John Carmack, who is considered to be one of the greatest programmers of all time, and he talks about how much he uses the debugger.
If its good enough for Jon Carmack, its good enough for me!