minidbg
Minimal, easy to integrate, multiplatform ANSI C debugger with serial interface
Summary
| Latest Version | Unknown |
|---|---|
| License | Unknown |
| CI Status | Failing |
| Stars | 9 |
| Forks | 1 |
| Open Issues | 0 |
| Last Commit | 2023-11-28 |
| Downloads | 0 |
| Last Indexed | 2026-09-07 06:08 |
Tags
Installation
nimble install minidbg
choosenim install minidbg
git clone https://gitlab.com/bztsrc/minidbg
OS Compatibility
| Platform | Linux | macOS | Windows | FreeBSD | OpenBSD | NetBSD | Android | iOS | WASM | Embedded |
|---|---|---|---|---|---|---|---|---|---|---|
| minidbg | ✓ | ✓ | ✓ | - | - | - | - | - | - | - |
Source
| Repository | https://gitlab.com/bztsrc/minidbg |
|---|---|
| Homepage | https://gitlab.com/bztsrc/minidbg |
| Registry Source | gitlab |
README
Mini Debugger
This is an extremely simple, small, dependency-free, easily embeddable multiplatform debugger written in ANSI C (and minimal Assembly). It is supposed to be integrated into kernels and bare metal programs, and it provides a VT terminal interface over serial line (with 115200 baud, 8 data bits, 1 stop bit, no parity). It's no more than 600 SLoC, and includes a fully featured disassembler, that's why the compiled code is so "big".
| Architecture | Code size |
|---|---|
| AArch64 | 124k |
| x86_64 | 74k |
Compilation
Just run
$ make
This will create libdbg.a. You can specify the architecture like this:
$ ARCH=aarch64 make
$ ARCH=x86_64 make
Then link with your kernel like
$ ld mykernel.o -o mykernel -L./dbg -ldbg
If by any chance you encounter linking issues with the static .a file, then you can use
$ make objs
And link with
$ ld mykernel.o ./dbg/*.o -o mykernel
Application Interface
Basic
Pretty simple, include $(ARCH)/dbg.h, and initialize interrupt handlers (if you haven't already). After that you'll get the
interactive debugger prompt if anything goes wrong in run-time. You can also place explicit debugger calls with breakpoint.
#include <x86_64/dbg.h>
void _start()
{
/* set up dummy Interrupt Service Routines if you haven't done already */
dbg_init();
/* from now on anywhere an exception happens in your code, the mini debugger
is automatically called. To explicitly invoke it, simply do */
breakpoint;
}
Integration with your ISRs
If you already have set up interrupt handlers, this is how you can invoke the mini debugger. You need to call three functions
in order: dbg_saveregs, dbg_main and dbg_loadregs. These are separated because the first and the third are written in
Assembly, while the second is in C.
void dbg_saveregs()
Stores the current register state.
On x86_64 it expects the stack to be consistent and to contain an interrupt frame (SS, RSP, RFLAGS, CS, RIP, code). This means for exceptions that do not place an exception code on the stack, you must push 0 before you call it.
On AArch64 the environment is read from system registers, so the stack is insignificant. However be aware that calling a function changes a register, so you must push x30 before you make a call. See aarch64/dbga.S.
void dbg_main(unsigned long excnum)
Invokes the debugger which provides the interactive prompt. The excnum argument is simply the number of the ISR, used to
identity the exception's cause.
void dbg_loadregs()
Restores the current register state. Note that there are similar considerations on AArch64 as with dbg_saveregs().
Usage
Qemu
Simply add a serial command line parameter, and you'll be able to control the debugger from the same terminal you are using to run qemu.
$ qemu (your specific arguments) -serial stdio
Real Machine
On IBM PC, the test machine must have a 16550 or compatible chip. Many new machines emulate that, so it's likely you have it. Then connect the test machine with an RS-232 cable or RS-232 USB converter to another PC running PuTTY (on Windows), or
$ minicom -b 115200 -D /dev/ttyUSB0
(on Linux). Use the appropriate device, for real serial ports (drived by 16550 chip) use /dev/ttyS0.
On Raspberry Pi, use an RS-232 cable or RS-232 USB converter and connect it to GPIO pins 14/15 on the Pi's side. On the other PC use the same utility as with x86_64.
Mini Debugger Prompt
When something blows off, you should see a similar output in PuTTY or minicom terminal:
Mini debugger by bzt
Synchronous: Breakpoint instruction
> _
You can get help with the ? or h command:
Mini debugger by bzt
Synchronous: Breakpoint instruction
> ?
Mini debugger commands:
?/h this help
c continue execution
n move to the next instruction
r dump registers
x [os [oe]] examine memory from offset start (os) to offset end (oe)
i [os [oe]] disassemble instructions from offset start to offset end
> _
Offsets can be in decimal and in hex, absolute addresses, or register relative, like
> x rbp-8 rbp+16
or
> i x30+0x200
Where you go from here depends on you. Mini debugger was never intended to be a fully featured debugger, instead simplicy, small code size and easy embeddability are its main goals, and to serve you as a skeleton for your own debugger. You can modify it, expand it, and add more commands if you'd like. Hints: add formatted print for the stack, single step instructions, ablilty to modify register values etc.
License
Licensed under the terms of the MIT license.
That's all folks!
Cheers, bzt