gdbforge: A Vim-Inspired Terminal UI for GDB — Embedded Linux, MPSoC, STM32, and Kernel kgdb

gdbforge: A Vim-Inspired Terminal UI for GDB — Embedded Linux, MPSoC, STM32, and Kernel kgdb

gdbforge — why another debugger UI?

If you spend your days on embedded Linux boards, Zynq MPSoC, STM32, or kernel kgdb, you already know the pattern: one terminal for GDB, another for minicom, a third for gdbserver logs, and an editor somewhere else. gdbforge is a project I built to keep the debugger’s power in the TTY while adding a Vim-inspired workspace — source, GDB console, IO, threads, call stack, and breakpoints in one keyboard-driven session.

It is not trying to replace your IDE. It is a cgdb-like terminal front-end for GDB (and optionally Delve for Go), extended with Lua scripts that automate the boring bring-up steps: spawn J-Link or OpenOCD, deploy to a board over scp, start gdbserver, or break into kgdb over UART.

In this article you’ll find:

  • What gdbforge is and who it is for
  • Where program I/O goes: internal :b io pane vs external terminal
  • The four Lua workflow families: embedded Linux, MPSoC, STM32, kernel kgdb
  • Links to the full documentation (with copy-paste recipes)

Quick start (PC)

git clone https://github.com/yairgd/gdbforge.git
cd gdbforge
go build -o bin/gdbforge ./cmd/gdbforge
gcc -O0 -g -o hello hello.c   # or your cross-built ELF
./bin/gdbforge ./hello

Inside the app: :help for the manual, n / s / c to step, :quit to exit.

Program I/O — internal tty vs external terminal

This matters for every user-space debug session — local or on a board.

Where stdio goesWhen to useHow
Internal IO paneSimple printf, line inputDefault — :b io (alias :b output)
External terminalFull TUI, curses, flood printing:lua external_tty, :lua terminal_debug, or :set inferior-tty
gdbserver windowRemote or local RSP debug:lua remotegdb (board) or :lua gdbserver_tui (same PC)

When stdio is routed externally, :b io shows a note only — you type in the other window. Switch back with :set inferior-tty internal.

export GDBFORGE_TERMINAL=mate-terminal   # or kitty, xterm, …
./bin/gdbforge ./my_tui
:lua terminal_debug ./my_tui run

Full write-up: Embedded Linux app debug guide

Lua workflows — four platform sections

Scripts live under lua/ in the repo. Copy what you need into .gdbforge/lua/, then run :lua <name> (Tab completes). Command names are the script basename — unchanged after install.

1. Embedded Linux user-space — :lua remotegdb

Deploy your binary to the board (scp when MD5 differs), start gdbserver over SSH in an external terminal, attach with target remote.

mkdir -p .gdbforge/lua
cp -r lua/embedded/remotegdb .gdbforge/lua/
export GDBFORGE_REMOTE_HOST=192.168.20.50
./bin/gdbforge ./hello
:lua remotegdb
:lua remotegdb ./hello 192.168.20.50 1234

📖 Embedded Linux debug guide


Bare-metal load, OpenAMP attach, and A53 kernel workflows. Scripts spawn JLinkGDBServer or OpenOCD + Digilent HS2 in the background; gdbforge stays responsive.

cp -r lua/mpsoc/cortex_r5 .gdbforge/lua/
export GDBFORGE_JLINK=/opt/JLink_Linux_V914a_x86_64/JLinkGDBServer
./bin/gdbforge ./your_app.elf
:lua r5_baremetal_jlink

Examples: a53_baremetal_jlink, r5_openamp_jlink, OpenOCD variants.

📖 MPSoC debug guide


Short, self-contained scripts (~100 lines) for STM32F405 — easy to copy and edit for other F4 parts.

cp -r lua/stm32/stm32f405 .gdbforge/lua/
./bin/gdbforge ./build/firmware.elf
:lua stm32f405_jlink      # J-Link SWD
:lua stm32f405_stlink     # ST-Link + OpenOCD

📖 STM32 debug guide


4. Linux kernel kgdb — UART, kdmx, Ethernet

One-shot UART break-in with :lua kgdb_kdmx, module symbols with lx-symbols, or Ethernet kgdboe with :lua kgdb_net. This is the workflow behind the kernel demo screencasts in the repo.

cp -r lua/kernel/kgdb_common lua/kernel/kgdb_kdmx .gdbforge/lua/
export GDBFORGE_KGDB_UART=/dev/ttyUSB0
export GDBFORGE_KGDB_VMLINUX=/path/to/vmlinux
./bin/gdbforge -g gdb /path/to/vmlinux
:lua kgdb_kdmx

📖 Kernel kgdb guide

What I like about this design

  • Keyboard-first — normal / insert / command modes, pane splits, :layout wide
  • Lua as glue — not a monolithic IDE; each workflow is a small script you can edit
  • Same UI for GDB and Delve-g dlv for Go, :lua dlv_ext_port for external Delve TTY
  • Probe in background — J-Link / OpenOCD spawn via gdbforge.spawn; Code pane stays usable

If you have used cgdb or live in the terminal during bring-up, the layout should feel familiar — with more structure for threads, breakpoints, and automation.

Documentation & source

ResourceLink
Docs site (search-friendly guides)yairgd.github.io/gdbforge
GitHub repogithub.com/yairgd/gdbforge
Lua cataloglua/README.md
User guidedocs/USER_GUIDE.md

Platform guides (good starting points):

Closing

gdbforge started as a way to stop juggling terminals during embedded bring-up. The Lua catalog grew organically — remotegdb for boards, MPSoC/STM32 probe scripts, kgdb for kernel work — each in its own directory with documentation and YAML meta for the docs site.

If you try it on a board or probe you care about, issues and PRs are welcome on GitHub. And if a workflow you use every week is missing, the intended extension point is simple: copy an existing script, edit the env defaults at the top, and :lua it.


Related on this blog: Python script plug-in to GDB · ZynqMP R5 RemoteProc notes · Debug Linux kernel with QEMU


Comments
comments powered by Disqus




Archives

2026 (2)
2025 (9)
2022 (3)
2021 (9)
2020 (18)
2014 (4)