Writing a Debugger
In a series of posts I will develop a debugger library that can be used to construct debugging experiments - repeatable, scripted, debugging tasks. I’ve written a tool like this in the past for a former employer but want to build a new, free, version. I’ll write the project first in C and then again in Rust. I’m taking this as an opportunity to learn Rust by building something substantial that I already understand.
An advantage of this kind of debugger is we have more control and we can make it very lightweight. gdb, as an interactive debugger, does a lot of work everytime the inferior stops and this overhead can perturb the timing of the inferior and make it harder to reproduce certain bugs. Our debugger will still have some overhead but it will have advantages over gdb in this respect.
To be specific, this debugger will target Linux x86-64 and perhaps Linux ARM if am ambitious enough.
The name of the C version of the debugger is Trap. The Rust version will be called Rusty Trap.
Roadmap
First, in C:
- DONE Create a minimal debugger in C and in Rust that can load and attach an inferior and run it to completion.
- DONE Build the infrastructure for the debugger project including
- Build scripts
- Test framework
- Continuous integration
- DONE Implement breakpoints at a fixed address and add callbacks to the system in C and in Rust
- At this point start building a proper API
- DONE Develop a formal state machine for handling events in a comprehensive way in C and in Rust
- Add support for debugging multiple threads.
- Load the DWARF debug symbol table and use symbol lookup to extend break points to handle function addresses.
- Use the debugger hook for dynamic library loading.
- Load line number information and use lookup to extend break points to handle line addresses.
- Load DWARF debug information for variables. Allow queries on variables.
- Add watch points.
- Develop some useful examples
- Using Rust, goto 1.
Following along
The source code is hosted on Github for trap the C debugger and rusty_trap the Rust debugger. The source may be farther ahead of these posts so I’ve tagged various commits with names that reflect the subheadings in these posts. You may need to checkout one of these tags to read through the version of the code relevant to this post.