Debugging is central to programming. You cannot be a good programmer without being good at debugging and vice-versa. And I would also say you cannot be good at debugging without taking advantage of the tools at your disposal. We don't need to use all the tools, but there are certain times when specific tools come in really useful.
Knowing your tools makes you a better programmer, but becoming (too) reliant on them for your debugging can lead you down a garden path and actually take you away from the correct answer.
When coding, we’ve got a model of what the program should be doing and the boundaries where expected behaviors diverge. The tools give us a model too. For example, when I'm stepping through my code in GDB, I have this kind of conceptual model of what's going on underneath. 90% of the time, I don't need to worry about what happens. I just accept the model that GDB gives me. But sometimes, things do happen (or do not happen) that can leave you astray if you don't understand what's really going on with the tools you're using.
This is why I think my talk with Dewang Li from Synopsys is fundamental. We explored some of the Linux C++ debugging tools available to us today and what's really going on underneath these tools.
Dewang and I looked at two categories of debugging tools - debuggers and checkers.
- The debuggers such as GDB and strace. These are our “traditional” debuggers that help us see what the program is doing as it goes. Watch it here.
- The time travel debuggers included in Software Failure Replay platforms such as rr and LiveRecorder. Time travel debuggers give us control over time, enabling us to step back in time to see what just happened. Time travelers tell you what your program just did, and let you step back and forth in time. Watch it here.
- The Dynamic Checkers such as Valgrind and Sanitizers. Dynamic checkers help us answer whether something X happened; for example, did a buffer overflow happen? And, if it did, where exactly did it happen in my program? Watch it here.
- The Static Checkers such as cppcheck and Coverity. Static Checkers help us with answering: could thing X happen (for example, memory leaks.) Dewang explains what Static Analyzers do, and walks us through a demonstration in which he writes a simple static checker. Watch it here.
Do watch the full talk here, and don’t forget to subscribe, like, and share!
Good luck debugging!
Don’t miss my next debugging tutorial: sign up to the gdbWatchPoint mailing list now.