Skip to content

etorth/tgdb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tgdb — Vi-like TUI front-end for GDB

tgdb is a terminal-based front-end for GDB, reimplemented in Python using Textual for the TUI and Pygments for syntax highlighting. It aims for 100% compatibility with cgdb in terms of keybindings, configuration, and behaviour.


Features

  • Split-screen TUI: syntax-highlighted source window above, GDB console below
  • Vi-like keybindings in the source window
  • Syntax highlighting for C, C++, Python, Rust, Go, Ada, Fortran, and more (via Pygments)
  • Visual breakpoint management: set/delete/enable/disable with Space
  • Executing line indicator: shortarrow, longarrow, highlight, or block styles
  • Regex search in source window (/, ?, n, N) with optional hlsearch
  • Marks (m[a-z/A-Z] / '[a-z/A-Z]) — local and global
  • File dialog (o) to browse and select source files
  • GDB scrollback buffer with configurable size and vi-style scroll mode
  • ANSI colour support in GDB output window
  • ~/.cgdb/cgdbrc config file support (all :set, :highlight, :map, :imap commands)
  • CGDB_DIR environment variable support

Installation

pip install -e .
# or
pip install textual pygments ptyprocess pyte
python -m tgdb

Usage

tgdb [OPTIONS] [PROGRAM [CORE|PID]]

Options:
  -d, --debugger DEBUGGER   Path to GDB executable (default: gdb)
  -r, --rcfile FILE         Configuration file (default: ~/.cgdb/cgdbrc)
  --args                    Pass remaining args as program + arguments to GDB
  --cd DIR                  Change to DIR before starting GDB

Examples:

tgdb myprogram
tgdb -d /usr/bin/gdb myprogram
tgdb --args myprogram arg1 arg2
tgdb myprogram core

Keybindings

CGDB mode (source window, default mode)

Key Action
ESC Stay in / return to CGDB mode
i Switch to GDB mode
s Switch to GDB scroll mode
j / Move cursor down
k / Move cursor up
h / Move left
l / Move right
Ctrl-f / PageDn Page down
Ctrl-b / PageUp Page up
Ctrl-d Half page down
Ctrl-u Half page up
gg Go to top
G Go to bottom (or line N with numeric prefix)
H / M / L Screen top / middle / bottom
/ Forward search
? Backward search
n / N Next / previous search match
Space Toggle breakpoint at current line
t Set temporary breakpoint
o Open file dialog
m[a-z/A-Z] Set mark
'[a-z/A-Z] Jump to mark
'' Jump to last jump location
'. Jump to executing line
Ctrl-W Toggle split orientation
- / = Shrink / grow source window by 1
_ / + Shrink / grow source window by 25%
Ctrl-l Redraw screen
F5 run
F6 continue
F7 finish
F8 next
F10 step
: Enter command mode

GDB mode (GDB console)

Key Action
ESC Switch to CGDB mode
PageUp Enter scroll mode
/ Command history
Ctrl-C Interrupt GDB
Enter Send command to GDB

Scroll mode (GDB console scrollback)

Key Action
ESC / q / i / Enter Exit scroll mode
j / Scroll down
k / Scroll up
PageUp / PageDn Page up / down
Ctrl-u / Ctrl-d Half page
gg / G Beginning / end of buffer
/ / ? / n / N Search

File dialog

Key Action
q / ESC Close dialog
j / k Move down / up
Enter Open selected file
/ / ? / n / N Search files

Configuration

tgdb reads ~/.cgdb/cgdbrc (or $CGDB_DIR/cgdbrc) on startup. Commands can also be typed interactively via :.

:set options

Option Abbrev Default Description
autosourcereload asr on Auto-reload changed source files
cgdbmodekey=KEY ESC Key to enter CGDB mode
color on Enable colour support
debugwincolor dwc on Show ANSI colours in GDB window
disasm dis off Show disassembly
executinglinedisplay=STYLE eld longarrow shortarrow|longarrow|highlight|block
selectedlinedisplay=STYLE sld block Same styles as above
hlsearch hls off Highlight all search matches
ignorecase ic off Case-insensitive search
scrollbackbuffersize=N sbbs 10000 GDB scrollback lines
showmarks on Show marks in gutter
showdebugcommands sdc off Show GDB commands sent
tabstop=N ts 8 Tab width
timeout to on Timeout on key maps
timeoutlen=N tm 1000 Map timeout (ms)
ttimeout on Timeout on key codes
ttimeoutlen=N ttm 100 Key code timeout (ms)
winminheight=N wmh 0 Minimum window height
winminwidth=N wmw 0 Minimum window width
winsplit=STYLE even src_full|src_big|even|gdb_big|gdb_full
winsplitorientation=STYLE wso horizontal horizontal|vertical
wrapscan ws on Search wraps around end of file

:highlight — customise colours

:highlight GROUP ctermfg=COLOR ctermbg=COLOR cterm=ATTRS

Groups: Statement, Type, Constant, Comment, PreProc, Normal, StatusLine, Search, IncSearch, SelectedLineArrow, ExecutingLineArrow, SelectedLineHighlight, ExecutingLineHighlight, SelectedLineBlock, ExecutingLineBlock, Breakpoint, DisabledBreakpoint, Logo, Mark, etc.

Colours: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, Brown/DarkYellow, LightGray/Gray, DarkGray, Blue/LightBlue, Green/LightGreen, Cyan/LightCyan, Red/LightRed, Magenta/LightMagenta, Yellow/LightYellow, White.

Attributes: bold, underline, reverse/inverse, standout, blink, dim, normal/NONE.

:map / :imap — key mappings

:map <F7> :step<Enter>
:map <F8> :next<Enter>
:imap <C-x> :quit<Enter>
:unmap <F7>
:iunmap <C-x>

Example ~/.cgdb/cgdbrc

set tabstop=4
set hlsearch
set autosourcereload
set executinglinedisplay=longarrow
set selectedlinedisplay=block
set scrollbackbuffersize=50000
set winsplit=even
highlight Statement ctermfg=Yellow cterm=bold
highlight Comment ctermfg=DarkGray
highlight Breakpoint ctermfg=Red cterm=bold
map <F5> :run<Enter>
map <F6> :continue<Enter>
map <F7> :finish<Enter>
map <F8> :next<Enter>
map <F10> :step<Enter>

Architecture

tgdb/
├── __main__.py          CLI entry point (argparse, launches app)
├── app.py               Main Textual App — layout, focus, event routing
├── gdb_controller.py    GDB subprocess (PTY), GDB/MI parser, callbacks
├── source_widget.py     Source code viewer widget (Textual)
├── gdb_widget.py        GDB console widget — scrollback, ANSI, scroll mode
├── status_bar.py        Status bar widget
├── file_dialog.py       File picker dialog widget
├── config.py            Configuration parser (cgdbrc format)
├── highlight_groups.py  Highlight group table and colour management
└── key_mapper.py        Key mapping with trie + timeout (KUI)

How it works

  1. Startup: TGDBApp reads ~/.cgdb/cgdbrc, spawns GDB via ptyprocess with --interpreter=mi2.
  2. GDB I/O: An asyncio task reads GDB output from the PTY.
    • Lines starting with ~ (console stream) → GDB widget
    • Lines starting with * or = (async events) → decoded for source position, breakpoints, etc.
  3. Source view: When GDB stops, the *stopped MI event provides the current file and line. The source widget loads the file (if needed) and positions the executing-line arrow.
  4. Breakpoints: The space bar sends -break-insert file:line via MI. Breakpoint events update the gutter markers.
  5. Key mapping: All keys pass through KeyMapper which resolves user maps (:map/:imap) before dispatching.

Differences from cgdb

  • Uses Textual (Python TUI framework) instead of ncurses directly
  • Uses Pygments for syntax highlighting (supports many more languages than cgdb's built-in flex lexers)
  • GDB/MI parsing is done in pure Python (no C++ gdbwire library)
  • Readline integration: basic history via up/down arrows (no libreadline)
  • The --tty / Ctrl-T separate TTY feature is not yet implemented

gdb

About

TUI front-end for GDB

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors