Hello! I’ve been working on writing a zine about debugging for a while (here’s an early draft of the table of contents).
As part of that I thought it might be fun to read some academic papers about
debugging, and last week Greg Wilson sent me some
papers about academic research into debugging.
One of those papers (Towards a framework for teaching debugging
[paywalled]) had a
categorization I really liked of the different kinds of knowledge/skills we
need to debug effectively. It comes from another more general paper on
troubleshooting: Learning to Troubleshoot: A New Theory-Based Design Architecture.
I thought the categorization was a very useful structure for thinking about how
to get better at debugging, so I’ve reframed the five categories in the paper
into actions you can take to get better at debugging.
Here they are:
1. learn the codebase
To debug some code, you need to understand the codebase you’re working with.
This seems kind of obvious (of course you can’t debug code without
understanding how it works!).
This kind of learning happens pretty naturally over time, and actually
debugging is also one of the best ways to learn how a new codebase works –
seeing how something breaks helps you learn a lot about how it works.
The paper calls this “System Knowledge”.
2. learn the system
The paper mentions that you need to understand the programming language, but I
think there’s more to it than that – to fix bugs, often you need to learn a
lot about the broader environment than just the language.
For example, if you’re a backend web developer, some “system” knowledge you
might need includes:
- how HTTP caching works
- CORS
- how database transactions work
I find that I often have to be a bit more intentional about learning systemic
things like this – I need to actually take the time to look them up and read
about them.
The paper calls this “Domain Knowledge”.
There are lots of debugging tools out there, for example:
- debuggers (gdb etc)
- browser developer tools
- profilers
- strace / ltrace
- tcpdump / wireshark
- core dumps
- and even basic things like error messages (how do you read them properly)
I’ve written a lot about debugging tools on this blog, and definitely
learning these tools has made a huge difference to me.
The paper calls this “Procedural Knowledge”.
4. learn strategies
This is the fuzziest category, we all have a lot of strategies and heuristics
we pick up along the way for how to debug efficiently. For example:
- writing a unit test
- writing a tiny standalone program to reproduce the bug
- finding a working version of the code and seeing what changed
- printing out a million things
- adding extra logging
- taking a break
- explaining the bug to a friend and then figuring out what’s wrong halfway through
- looking through the github issues to see if anything matches
I’ve been thinking a lot about this category while writing the zine, but I want
to keep this post short so I won’t say more about it here.
The paper calls this “Strategic Knowledge”.
5. get experience
The last category is “experience”. The paper has a really funny comment about this:
Their findings did not show a significant difference in the strategies
employed by the novices and experts. Experts simply formed more correct
hypotheses and were more efficient at finding the fault. The authors suspect
that this result is due to the difference in the programming experience between
novices and experts.
This really resonated with me – I’ve had SO MANY bugs that were really
frustrating and difficult the first time I ran into them, and very straightforward
the fifth or tenth or 20th time.
This also feels like one of the most straightforward categories of knowledge to
acquire to me – all you need to do is investigate a million bugs, which is our
whole life as programmers anyway :). It takes a long time but I feel like it
happens pretty naturally.
The paper calls this “Experiential Knowledge”.
that’s all!
I’m going to keep this post short, I just really liked this categorization and
wanted to share it.