Readit News logoReadit News
Posted by u/recvonline 3 years ago
Ask HN: How do you get better at debugging/finding a solution?
Software dev with more than 10 years of experience. I always gotten praise by colleagues and companies I worked for. But, there are always moments where, without help from a colleague, I wouldn't have found a solution to a problem.

When joining a new company, 2 months in, and facing a problem where code wouldn't compile, I dig deep into the codebase but for the love of me, can't find a solution.

I wonder, is that normal? Or how can I say: "I don't care, if I am alone, I can figure this out and solve it."

Did anyone here evolve from this state of reliance of others and turned themselves into a "I can do it myself in a good amount of time"?

xsmasher · 3 years ago
* start logging shit, even things you know to be true / can't possibly be the problem. Somewhere your model of the code is broken, and you need to test find the breakage (model needs correction, or program needs correction).

* Split the problem space. Payment messages are not getting to the slack channel. Well, is it a bug in receiving payments, or a bug sending slack messages? Check if the payments are hitting the database. If no, you know it's on the input side. If yes, you know it's on the output side.

* Explain the problem to someone else; if you're alone write it up like a question you're going to post on a forum, with as much detail as possible. This must engage a different part of the brain, because often I'll figure out the issue while writing it up I'll reveal some clue while logging example output to add to the post.

Longer-term, teach a programming class! You'll get very good at debugging issues because you'll encounter a lot of other people's bugs, and you'll get a feel for what causes particular failures.

Also, don't feel any shame in asking others for help. Even senior devs get blocked, and they ask other seniors, or juniors, or if juniors are not available a rubber duck will suffice.

xsmasher · 3 years ago
I forgot one - if you start thinking there's a bug in a library, reduce your code to the smallest example that reproduces the problem. If you get it down to 5-6 lines you're going to either (1) remove something along the way that fixes the problem and gives you a clue or (2) you will have something you can post in message boards when you ask for help.

You'll also have a shortlist of functions that you can search for in stack overflow, and compare you example to theirs.

kevan · 3 years ago
>Somewhere your model of the code is broken, and you need to test find the breakage (model needs correction, or program needs correction).

Most of the harder bugs I run into fall into this category. Great list of techniques to use. For when I'm really stumped I go into a more formal scientific method to the splitting the problem space approach. Formulate a hypothesis that if answered will reduce the search space, either by ruling in or ruling out things. Write it down - this is the important part, test it, repeat.

It's slow but usually helps me keep forward momentum. Worst case it at least creates a list of things that need better logging to figure out what's going on

NBJack · 3 years ago
+1 to this. Make ZERO assumptions about the problem, and observe everything you reasonably can. In the increasingly (?) service-oriented architecture world, that includes fundamentals on your platform (i.e. I recall the first time I root-caused an issue that turned out to be an AWS bug) and taking the time to monitor external dependency changes (i.e. a service change, a code push, someone reverting stuff, etc.)

I also can't agree more with no shame in asking others. I would go as far as to say if you aren't asking others, you are going down a dangerous path of assuming you can solve the world's problems by yourself.

spiffytech · 3 years ago
Something I read forever ago and can't find a link for:

Keep a debugging journal. Take notes on every step you take and its results. It's easy to go in circles because you forget what you tried or forgot some detail of its outcome. Seeing a summary of what you already know helps you rule out possibilities and inspires new ones.

I often forget to do this or feel like "I can handle this bug without a crutch". Yet every time I actually journal the process it's helpful.

HeyLaughingBoy · 3 years ago
I find this useful also, especially with new technology where I may not already have a good mental model of how it works.

I generally use Notepad++ and it's often just a set of notes about the value of important variables in certain files @ a particular line of code or at a particular time. I find that seeing that big picture at a glance can often give me immediate insight into what's happening. Something you can't always see when you're focused on a few lines of code in a method.

greenyoda · 3 years ago
A journal also makes it much faster to jump back into a productive state after that inevitable interruption. (That interruption could be a meeting, or an emergency that forces you to drop everything and work on a higher-priority issue for several days.)

You can also refer back to your journal to remind yourself how you fixed that similar problem months ago.

Of course, a journal doesn't have to be limited to debugging. It's useful for development too.

shreyshnaccount · 3 years ago
there has to be a way to make this more streamlined and run experiments automatically, right?
luisgvv · 3 years ago
- Create a call stack map and write it down - This will give you an overview of which classes, functions, methods, paths are being used.

- People look down on console/logging, but it's useful specifically when there are race conditions or too many variables. It's way better to have several outputs and logs rather than a "standstill" picture you can only look while using the debugger.

- "Learn to debug" - This advice is thrown too vaguely around, but I'll tell you that the 2 essential pieces that helped me debug are 1- using watches to keep an eye on variables, props that are relevant to the problem 2- Use conditional breakpoints - About the 90% of the people I've paired programmed with don't know about it or even if they know it exists they don't use it and when I put in place some conditional break points they look with awe at how it can make a change.

- A somewhat counter intuitive or controversial advice: read the code involved and look for inconsistencies, dumb scenarios, flags, awful named variables and clean them! - Sometimes my attention span and memory range is entangled with garbage code that makes it harder to reason about. By throwing away the pieces I don't like and improving on them I get the benefit that in the future it will be easier to maintain and reason.

half0wl · 3 years ago
> Create a call stack map and write it down

(personal anecdote) I strongly agree with this. Writing it down is very important. Whenever I trace through a call stack, I tend to construct a visualization of it in my mind (in the form of a DAG + each root starting with the caller, if you will). But I could never hold that image especially when it gets too complex. Forcing myself to write it down helped me a lot - it doesn't matter if it's messy writings or drawings, somehow the _act of writing_ just helped me so much in reconciling concepts and connecting the dots.

tstrimple · 3 years ago
> - People look down on console/logging, but it's useful specifically when there are race conditions or too many variables. It's way better to have several outputs and logs rather than a "standstill" picture you can only look while using the debugger.

It also works across every programming language and development stack. It can be setup across network and application boundaries. Debugging skills with logging is extremely portable.

wnolens · 3 years ago
I felt like this before. Now it feels more a matter of time. I got significantly better by observing talented colleagues and picking up their strategies, some like:

Have a hypothesis and try to prove otherwise.

Start cordoning off parts of the codebase where the problem ISN'T.

Leave printf breadcrumbs to trace execution.

I find my less capable colleagues make the mistake of false assumptions, like some subroutine is executing or what state an object is in without proving it to themselves. That keeps your investigation from proceeding without luck on the larger problems.

ilitirit · 3 years ago
This is what my Mathematics Lecturer told us years ago when we had trouble understanding why some approaches worked for some problems, but not others.

"You need a few more years of study before you can fully understand. But! You have a 600 page textbook. Do every exercise in that book. When you can do that without assistance, get another 600 page textbook and repeat."

He was trying to get us to build an intuition for certain class problem solving, while at the same time saying "Shut up and calculate".

I find that problem-solving in the programming space is the same. Just keep doing things. You'll develop an intuition for it eventually.

groffee · 3 years ago
It's probably not so much your colleague that helps but the act of just talking through a problem, inanimate objects work too https://en.wikipedia.org/wiki/Rubber_duck_debugging

What also helps is just shutting the computer off and going for a walk, generally the moment you step away you'll figure it out!

nicbou · 3 years ago
If rubber ducking fails, try to write a GitHub issue that starts with "it's probably my fault, but".

By the time you're done describing the problem and its symptoms, you'll have a solution.

I can also recommend going for a walk. I usually return from long motorcycle trips with the best ideas. Tea on the balcony is also effective.

digitalsushi · 3 years ago
In college, when we got stumped on a CS assignment, we'd play Mario Kart, and while focusing on the game, we'd complain about the assignment. Very often, some quick, lazy criticism at our attempts would render an astute observation we wouldn't have made if not distracted by the game.
Fnoord · 3 years ago
> What also helps is just shutting the computer off and going for a walk, generally the moment you step away you'll figure it out!

Underrated. Diffused mode of brain.

hybridtupel · 3 years ago
Working for a bigger company I’m hesitant to go for a walk as that would mean I need to stay longer in the afternoon/evening. Even when going for a walk solves the problem, there is still little acceptance to count it as working hours. I think this mentality should shift somehow as it would benefit the company and the employee.
samuell · 3 years ago
I have often found myself being able to dig forward way after many of my peers (not all) are out of ideas. I have seen a shift in my own ability to debug problems after I realized that with increasing "hardness" of the bug, you need to just increase the level of systematicness and rigor of your method.

The very first thing should probably be to carefully check which commit introduced the error, and then carefully study the code changes in that one for clcues.

After that, and possibly based on that, what probably most people will do is start their debugging process by running a debugger through some suspicious parts of the code, based on varying degrees of well-informed suggestions.

For problems that escape those first tries though, what you often need to do is to start a systematic process of ruling out possible sources for the bug. In many ways this resembles scientific studies where you try to control as many variables as possible, and also include control samples with known states, trying to zoom in on only the particular variable you are studying without noise from other things.

That can mean feeding the system or code under study with carefully set up data for which you know what the effect should be, and then carefully trying to change each part of it and observing the outcomes. Things like that.

In my experience, this type of effort will eventually most often lead to the solution. The main challenge I think though, is to realize how deeply you might need to go with the systematization and automation of things, to really rule out possible sources and start zooming in on the general area around where the bug is. You might need to take some real drastic measures, and this is where I see most people who fail, don't go far enough. Here you might need to really get away from the screen to get your thoughts flowing more freely ... but not in an undirected way, but rather trying to answer the question "How can I do this in an even more systematic way ... to rule out even more possible sources, or identify unexpected behavior".

Not super easy to put into words, but this is in my experience the way to go.

Finally, one caveat is that there are certain things you should probably check before even going the systematic path. Things that can totally screw things up so that whatever you do, you never get any systematic pattern of behavior or behavior change. These things often are related to caches in various form. Make sure to turn off any and all kinds of caches in the system. They will almost guaranteed drive you insane otherwise.

VoidWhisperer · 3 years ago
> The very first thing should probably be to carefully check which commit introduced the error, and then carefully study the code changes in that one for clcues.

Git bisect is a very useful tool for this assuming you have an easily reproducible case for the problem. (So generally it is decidely less useful when the bug is the result of a race condition)

Communitivity · 3 years ago
I find many problems made easier by applying cross-disciplinary knowledge.

Debugging has been one of those for me.

A long time ago I helped my mother with a murder mystery by researching how doctors diagnose things (I was a professional information broker then, with Dialog, Lexus/Nexus, GratefulMed, etc.), as much as I could without going to medical school. I learned a lot about differential diagnosis. That got me hooked on medical shows, where I learned a little more. At some point after that I wondered if I could apply differential diagnosis methods to debugging. Because there are often multiple possible causes for a bug, I found the differential diagnosis approach to work amazingly well for me.

I call this process D3 (Differential Diagnosis Debugging).

Below is roughly how I apply it. I am working on a book including this as a couple chapters, but that won't be out for at least another year. The material in this post is in the book, so I am told I must copyright anything smacking of an excerpt.

First, capture all the relevant details of the expected behavior. Create a unit test (or tests) to confirm the expected behavior.

Next, capture all the differences between the observed behavior and the expected behavior (the 'symptoms').

Then, examine those differences to come up with possible hypothesis about the causes.

After that, use a concept similar to Karnaugh Maps [1] to determine a sequence of small discrete unit tests whose truth (if true hypothesis could be true) determines a T or F for each hypothesis. If you wind up with more than one T then you need more tests (diagnostic testing).

Once you have a confirmed hypothesis, apply a fix an rerun all your tests. Rinse and repeat as needed, if needed (treatment), until all of your expected behavior tests pass.

Unpublished Work © Copyright 2022 William A. Barnhill, Jr. Some rights reserved. You may apply the D3 process as described herein; you may not incorporate the D3 process into a written work, a web site, or an email; you may discuss the D3 process if full attribution to the author is given.

Please don't hate me for the above folks. Been told I need to include that if I want to get published.

[1] https://en.wikipedia.org/wiki/Karnaugh_map

dsr_ · 3 years ago
Copyright applies to the specific words or notes that you use. You gain copyright (in the US) immediately upon fixating the words (i.e. writing them or recording them). It never applies to underlying ideas or methods.

Trademark applies to special identifiers of products and services.

Patents apply to inventions. It may apply to processes, given tangible form.

In short, you are taking bad advice. Get better lawyers.

In the alternative that you think your licensing terms mean anything:

1. By reading these words you agree, on behalf of yourself and your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that you believe I have entered into with you or your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges.

2. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.