Need advice on writing Linux debuggers:

Hi everyone,

Some context: I tried writing a Linux debugger a while back as a learning project and to improve my programming skills. I was able to write code that allowed basic assembly level debugging functions like setting breakpoints, reading and writing register values, stepping over instructions. I decided that I should move to implementing source level debugging features which meant I would have to parse DWARF and ELF files. I wanted to make this project without using any libraries and so I started reading the DWARF and ELF specification. I was quickly overwhelmed by DWARF spec and after days of trying to understand it I abandoned the project.

I am thinking of giving it another shot and would like some advice on how to proceed with the project.
  • If I decide to still try to write this project from scratch, how should I make my way through the DWARF spec? Should I read and understand the entire spec first or read only those parts that are required to implement the feature I am working on at any given time? Any advise on parsing huge spec like DWARF would be helpful.
  • I would like to get some DWARF library suggestions if I decide to use libraries. Libdwarf(https://www.prevanders.net/dwarf.html) seems to be a good choice but would like to know if there is a better library.
  • Lastly any advice/resources for writing a Linux debugger(or any debugger in general) would also be really helpful.


Thanks
- Karan

Edited by Karan Joisher on Reason: Initial post
I wrote this blog post a few years ago on my experience using libdwarf.

I made it into a ~10K-line debugger and ~2K of those where dedicated to elf and dwarf parsing. I parsed only the parts of the format that I encountered and asserted any time I stumbled upon a part of the standard I hadn't implemented yet. I like working that way because I never spend time on something that won't be immediately useful and I always have a use case to test new code.

If I remember correctly, to find the DWARF info inside the binary you first have to parse the ELF format. libc6-dev provides the elf.h file that gives you the definition of structures such as the ELF header Elf64_Ehdr and Section headers Elf64_Shdr. I followed this document to do that. I think starting with ELF parsing is a nice way to ramp up to the parsing of the more intricate DWARF format.

Have fun programming!
I can't comment on any libraries, but I implemented what I needed from the ELF and DWARF specs for getting backtraces. Like debiatan, I just started parsing things I understood/encountered and asserted on anything that wasn't implemented. As for how to read the DWARF spec, I just read the beginning of section 2 (maybe up to 2.5?) and then jumped to what I cared about (e.g. 6.2 Line Number Information or 6.4 Call Frame Information). If anything comes up that you don't understand, it's usually not hard to figure out where it's defined or described. I'll also note that besides the ELF and DWARF specs, you'll probably need the AMD64 ABI since some things like register mapping are designated as platform-specific by ELF/DWARF.