God bless I don't have to write LLDB myself...
qbdbg is a simple Linux debugger written in C using ptrace API. The sole idea of this project is to create a CLI debugger as a way of learning about debuggers, processors, signals, memory, breakpoints and process introspection.
The debugger is split into three responsibility layers
cli- handles user input, parsing of commands and display of CLI interface.dbg- handles state management of debugger context and prepares data to be forwarded tooslayer.os- handlesptraceAPI and system calls.
CLI interface layer has no idea about the underlying OS layer. Commands and execution flow travel downwards through the layers, while state and data are bubbled back up. This unidirectional flow decouples them from responsibilities, allowing for cleaner and more maintainable style of the codebase.
After issuing launch command, the debugger uses fork() to spawn a child process. Child process calls ptrace(PTRACE_TRACEME, ...) to allow the debugger process to trace its execution. The control flow is redirected to the parent where the user can send in debugger commands through a terminal interface integrated into the debugger.
The architecture currently supports only Linux operating systems. Due to the projects architectural nature it allows for swapping out the ptrace backend with the Win32 Debuggin API in the future to support Windows.
- Reading and writing CPU registers (x86_64 support only)
- Spawning and attaching to a child processes
- Setting software breakpoints
- Support for multiple commands with abbreviations
- Handling multithreaded processes
- Linux (requires
sys/ptrace.hand ELF binaries) - GNU Readline libary (e.g..
libreadline-dev) - C compiler (defaults to
clang) cmake(3.20+)make
Before proceeding to building the project ensure you have installed all prerequisites. Build process has been simplified with a Makefile wrapper around CMake.
make runmakeormake build- Configures (if necessary) and compiles the project. Executable gets placed inbuild/{BUILD_TYPE}/qbdg.make run- Builds the project and runs the binary.make configure- Runs Cmake to generate build files without compiling the code.make clean- Deletes entire/builddirectory removing all compiled and cached files.
It is possible to customize the build behavior by passing variables to make command. By default the script uses clang compiler and builds in Debug mode.
Changing the build type is done by overriding the BUILD_TYPE variable:
make build BUILD_TYPE=ReleaseChanging the compiler is done by overriding the exported CC variable:
make build CC=gccTo run the debugger run the compiled binary in /build/{BUILD_TYPE} directory.
# Debug mode
./build/Debug/qbdbgDebugger supports --help and -h flags
qbdbg - a lightweight x86-64 debugger
USAGE
qbdbg [options] [program [args...]]
OPTIONS
-h, --help Print this message and exit
-v, --version Print version
Once inside the debugger you will see the debugger CLI interface starting with qbdbg> prompt.
launch <path_to_binary> [flags...]- Launches process to be debuggedquit- Exits the debuggerrs <register> <value>- Sets a register to a provided valuerg [(optional) registers...]- Without any arguments all registers get displayed. It is possible to pass individual registers as arguments to get their values