English | 简体中文
GDB helper framework for debugging RTOS-based embedded firmware.
GDR runs inside the GDB Python interpreter and provides three layers of debugging support, following the approach popularised by the GEF and the Asterinas GDB helper:
- Aggregate commands —
rtthread threads,rtthread semaphores, etc. only handle what GDB expressions cannot easily do: iterate collections and tabulate results. - Pretty-printers — fold noisy kernel object (
rt_mutex,rt_semaphore,rt_thread) into one-line summaries sop,bt fullandinfo localsstay readable. - Convenience functions —
$gdr_thread("main"),$gdr_threads(),$gdr_object(type, name)returngdb.Valueso you can keep using native GDB expressions for the actual field inspection.
| RTOS | Versions | Status |
|---|---|---|
| RT-Thread | 3.1.x,4.0.x,4.1.x | implemented; Cortex-A9 verified across both ranges, RV64 from 4.0.4 |
| FreeRTOS | — | not yet (deferred) |
Core implementation complete: GDB bridge, layout engine, pretty-printers, convenience functions, aggregate commands, and QEMU closed-loop verification on Cortex-A9 and RISC-V RV64 targets.
-
Python-enabled GDB — verify the interpreter GDB will actually use:
gdb --nx --quiet --batch -ex 'python import sys; print(sys.version)'The reported version should be 3.10 or newer for a supported configuration. GDB with older python version may work but not tested.
- ARM / RISC-V: download a prebuilt toolchain from xPack Dev Tools
- Other platforms: build from source with
./configure --target="<target-triple>" --enable-targets=all --with-python - See also: Installing GDB for ARM | Interrupt
-
Debug symbols — ensure the RTOS image under debug includes DWARF / ELF symbols (do not strip the
.elfyou attach GDB to).
Download the RT-Thread archive from GitHub Releases.
Use .tar.gz on macOS or Linux:
curl -LO https://github.com/flespark/gdr/releases/latest/download/gdr-rtthread-latest.tar.gz
tar -xzf gdr-rtthread-latest.tar.gz
cd gdr-rtthreadand .zip on Windows:
Invoke-WebRequest https://github.com/flespark/gdr/releases/latest/download/gdr-rtthread-latest.zip -OutFile gdr-rtthread-latest.zip
Expand-Archive -Path .\gdr-rtthread-latest.zip -DestinationPath .
Set-Location .\gdr-rtthread(gdb) source gdr.py
(gdb) gdr init rtthread 4.0.5
[gdr] setting up RT-Thread v4.0.5...
[gdr] config: smp=True heap=small_mem sem=True mutex=True mb=True mq=True
[gdr] layout: 10 structs, 2 list hooks
[gdr] rtthread commands registered (alias: rtt)
[gdr] RT-Thread support ready. Type 'rtthread help' for commands.
(gdb) rtthread threads
(gdb) rtthread semaphores
(gdb) rtthread system
(gdb) p $gdr_thread("worker1")| Command | Description |
|---|---|
rtthread threads |
List all threads (name/state/priority/sp/stack_size/stack_used/max_stack_used/entry) |
rtthread semaphores |
List semaphores (name/value/addr) |
rtthread timers |
List timers (name/state/mode/type/ticks/callback) |
rtthread objects [type] |
List kernel object counts, optionally filtered by type |
rtthread system |
System summary (tick, current thread, object counts, heap) |
Single-object inspection is delegated to convenience functions + GDB expressions, not dedicated commands.
| Function | Returns | Example |
|---|---|---|
$gdr_thread(name) |
struct rt_thread gdb.Value |
p $gdr_thread("worker1") / p $gdr_thread("worker1").stat |
$gdr_threads() |
array of struct rt_thread * |
p $gdr_threads() / p *$gdr_threads()[0] |
$gdr_object(type, name) |
kernel object gdb.Value | p $gdr_object("SEMAPHORE", "my_sem") |
Prefer the quoted type name in scripts and automation:
$gdr_object("SEMAPHORE", "my_sem"). Bare names such as SEMAPHORE are
registered as GDB macros only when the target ELF does not already define
them; on conflict GDR skips the macro and warns, and the quoted form still
works.
Registered automatically on source gdr.py. Kernel wrapper types are
folded into one-line summaries based on layout summary fields:
(gdb) p mutex
$1 = Mutex(name="lock1", value=0, hold=1, owner="main")
(gdb) p semaphore
$2 = Semaphore(name="sem1", value=3)
(gdb) p thread
$3 = Thread(name="worker", stat=READY, current_priority=5)Users specify the RTOS and major version explicitly; there is no auto-detection of the RTOS type or version (detection logic is fragile across attach/remote scenarios). Kernel config features (SMP, heap manager kind, enabled IPC components) are probed automatically by symbol presence at startup.
RT-Thread 3.1.x is verified on the Cortex-A9 QEMU BSP only. The upstream QEMU RV64 BSP starts at RT-Thread 4.0.4, so RV64 verification covers 4.0.4 through 4.1.1.
rtthread/layout.py is the single place that knows RT-Thread struct
layouts. When an RT-Thread kernel struct changes (new field, renamed
member, shifted offset), that file — and its QEMU smoke test — must be
reviewed together. See docs/architecture.md for the rationale.
uv sync --group dev # create .venv and install dev dependencies
uv run pre-commit install # activate git hooks
uv run ruff check . && uv run ruff format --check .
uv run pytest tests/ -v # requires QEMU + RT-Thread firmwarCI runs on CNB (Cloud Native Build); pipelines are
defined in .cnb.yml (lint, the GDB 12 compatibility baseline, and Cortex-A9
and RV64 QEMU matrices). To reproduce the current ARM and RV64 QEMU matrices
locally in a Podman machine:
ci/validate-podman.shThe script builds ci/Dockerfile for linux/amd64 and uses the pinned xPack
toolchains. Start a Podman machine before running it.
See AGENTS.md for the full contributor guide.