Last week I wrote a short post entitled “Is honesty the best policy?” in response to part of an article written by John Graham-Cunning. That post addressed one of the issues I took with John’s article. The other issue, and far more pressing issue, were his comments about debuggers.
Debuggers are sometimes a crutch… The reason I don’t use a debugger much is I think it leads to lazy thinking. Many people when faced with a bug reach for the debugger and dive into setting breakpoints and examining memory or variable values. It’s easy to become enamored with such a powerful tool, but a little bit of thinking tends to go a long way. And if your program is so complex that you need a debugger you might need to go back to #2.
Once again, I’d like reiterate an important point: as programmers, we do tend to work with large and often unfamiliar, non-standarized codebases, and debuggers can be an invaluable tool in understanding. Its true that alot of programmers can use debuggers as a crutch rather than thinking about their code and what could be causing a certain bug. However, just because some people can misuse and abuse a tool does not mean we should cast it aside.
One of the options that John presents is heavy use of log output to identify whats going wrong with a program. As a game developer, using Unreal, this presents several issues.
- A launch and shutdown log for UDK is around 150 lines. Thats before actually doing anything.
- UDK has 62 different built-in log categories (63 if you include the default category)
- Script code for UDK ticks once every 0.0169 seconds (60 times a second).
Combining all of these elements together, relying purely on log output can be a massive headache. Imagine trying to debug something that writes to your log 60 times a second. Or imagine trying to debug a physics engine, or a renderer, purely through log output. Or perhaps even worse, multiple interacting subsystems that might not necessarily support log output – writing shader code, for instance. In the case of shaders, we do have tools that can modify the code in realtime, observe values and change them. Because they are programs that are run directly on the GPU, we can’t log anything during shader processing. All we get is an input, and an output, and for anyone who has written shader code, you’ll know that alot can go on inside a shader. And, once again, its going on at 60 times a second.
We aren’t so lucky as to be able to edit code and see realtime results in most languages, although some people have been working on it. Clearly this is an ultimate goal that we may not reach anytime in the near future, at least not in the case of large, complex 3D engines. But as developers, its all about being able to fail fast and debuggers have a place in helping us fail faster.
Debuggers don’t lead to lazy thinking – lazy programmers lead to lazy thinking. Debuggers are another fantastic tool in a programmers arsenal. Rather than demonising them, we should aim to educate people on their use.