- 开发工具
【免费下载链接】gdbgui
Browser-based frontend to gdb (gnu debugger). Add breakpoints, view the stack, visualize data structures, and more in C, C++, Go, Rust, and Fortran. Run gdbgui from the terminal and a new tab will open in your browser.
导读
gdbgui是一个基于浏览器的 GDB(GNU Debugger)前端,你只需在终端运行gdbgui,浏览器便会打开一个新的调试界面,即可对 C、C++、Go、Rust、Fortran 等语言编译出的程序进行可视化调试。本文以官方文档 docs/screenshots.md 的功能截图总览为骨架,逐模块讲解 gdbgui 的界面布局、每项核心能力的操作方式与背后的源码实现,读完你将对“加载程序 → 控制执行 → 查看栈/线程 → 设置断点 → 观察变量/表达式 → 检查内存与寄存器 → 使用 gdb 控制台”的完整调试链路有系统认识,并能借助 gdbgui/src/js 下的前端源码快速定位对应功能。
启动界面:加载二进制文件与命令行参数
gdbgui 启动后进入 screenshots/ready.png 所示的就绪界面。加载被调试程序的方式与在命令行中直接执行完全一致:在界面中输入二进制文件路径和运行时参数(args),就像在 shell 里调用它一样(见 docs/screenshots.md 对 screenshots/load_binary_and_args.png 的说明)。
两点关键行为值得注意:
- 二进制路径会被 gdbgui 记住,当 gdbgui 之后再次打开时,二进制文件会被自动恢复,无需重复输入;
- 与纯 gdb 相同,参数直接按空格分隔,例如
./hello --verbose 3。
仓库中 examples 目录提供了多种语言的测试程序,例如 examples/c/hello.c、examples/cpp/hello.cpp、examples/golang/hello.go、examples/rust/src/main.rs,编译后即可作为 gdbgui 的调试目标快速验证各功能。
整体界面效果如下:
控制按钮:运行、继续、单步与指令级调试
gdbgui 提供了一组直观的执行控制按钮,从左到右依次为:Run(重新运行)、Continue(继续)、Next(单步跳过)、Step(单步进入)、Return(跳出函数)、Next Instruction(NI)、Step Instruction(SI)(见 screenshots/controls.png)。
这组按钮的完整实现位于 gdbgui/src/js/ControlButtons.tsx,其内部调用GdbApi.click_run_button()、GdbApi.click_continue_button()等方法,最终映射为对应的 GDB/MI 命令。各按钮对应的键盘快捷键(从按钮title中可以查到)如下:
| 按钮 | 含义 | 快捷键 |
|---|---|---|
| Run | 从头启动被调试程序 | r |
| Continue | 继续执行直到命中断点或程序退出 | c |
| Interrupt (SIGINT) | 向 gdb 进程发送中断信号以暂停运行 | — |
| Next | 单步跳过(step over)函数调用 | n或→ |
| Step | 单步进入(step into)函数调用 | s或↓ |
| Return | 跳出(step out)当前函数 | u或↑ |
| Next Instruction (NI) | 执行一条机器指令,跳过函数调用 | m |
| Step Instruction (SI) | 执行一条机器指令,进入函数调用 | , |
当程序处于运行状态时,位于 Continue 右侧的中断按钮会通过Actions.send_signal("SIGINT", ...)向 gdb 进程发送 SIGINT 以暂停被调试程序(见 gdbgui/src/js/ControlButtons.tsx)。
反向调试:基于 rr 的倒带执行
如果底层环境支持反向调试——例如使用 Intel CPU、运行 Linux 且配合 rr 录制程序执行——gdbgui 允许你反向调试(见 screenshots/reverse_debugging.png)。
实现上,ControlButtons通过store.connectComponentState(this, ["gdb_pid", "reverse_supported"])订阅了reverse_supported状态:当该状态为真时,Continue / Next / Step / NI / SI 按钮的提示文案会额外追加“shift + 对应按键进行反向执行”的说明(例如shift + c反向 Continue、shift + n反向 Next),见 gdbgui/src/js/ControlButtons.tsx。
Stack / Threads:线程、栈帧与调用栈导航
在栈/线程面板(见 screenshots/stack_and_threads.png)中,你可以:
- 查看所有线程,每个线程头部显示 target-id、线程 id、core、状态与名称;
- 查看当前线程的完整调用栈;
- 对非当前线程显示其当前所在帧;
- 通过点击在栈帧之间切换,或在线程之间切换;切换线程后,变量检查会针对该线程的当前帧进行。
该面板由 gdbgui/src/js/Threads.tsx 实现:Threads.select_frame(framenum)会设置selected_frame_num并调用GdbApi.select_frame(framenum);栈表的每一行包含函数名、文件(可点击跳转到源码)、地址(可点击进入内存查看器)和函数参数四列,当前选中帧以加粗显示,其他可点击帧会弹出“点击选择此帧/此线程”的提示。
向被调试进程发送信号
gdbgui 允许你从操作系统支持的信号列表中任选一个信号发送给 inferior(被调试)进程。例如:
- 发送
SIGINT可以模拟在纯 gdb 中按下CTRL+C,用于中断被调试进程; - 如果被调试进程因故挂起,可以发送
SIGKILL强制终止,等等(见 docs/screenshots.md 对 screenshots/send_signal.png 的说明)。
前端在 gdbgui/src/js/Actions.ts 的send_signal(signal_name, pid)中通过/send_signal_to_pid接口将信号送达指定进程,后端则由 gdbgui 服务器代为向被调试进程的 pid 发送对应信号。
源代码视图:断点、符号自动补全与汇编
源代码面板是 gdbgui 的核心区域(见 screenshots/source.png),支持:
- 查看源码与汇编,通过点击行号(gutter)添加/移除断点;
- 在源码查看器上方有一个下拉框列出编译目标的所有符号,并支持自动补全;
- 提供两套配色方案:深色主题(monokai)与默认浅色主题。
这些能力由 gdbgui/src/js/SourceCode.tsx 与 gdbgui/src/js/Breakpoints.tsx 协作完成:
SourceCode.click_gutter(line_num)调用Breakpoints.add_or_remove_breakpoint(fullname, line),后者通过-break-insert/-break-delete等 GDB/MI 命令增删断点(见 gdbgui/src/js/Breakpoints.tsx 中的add_breakpoint/delete_breakpoint);- 断点面板还支持:勾选启用/禁用断点(
-break-enable/-break-disable)、设置断点条件(-break-condition)、显示命中次数、识别父/子断点(例如在 inline、模板或歧义位置自动创建的断点树,见is_parent_breakpoint/is_child_breakpoint的判定逻辑),并显示断点所在行的源码文本缓存; - 源码行渲染时,行号列通过
gutter_cls区分普通断点、禁用断点与条件断点;gdb 暂停所在的当前行会以paused_on_line样式高亮并自动滚动到可见位置(make_current_line_visible)。
汇编视图与缺失源码时的回退
开启汇编后,每条源码行下方会对应显示机器指令(见 screenshots/source_with_assembly.png),其中加粗的指令行表示 gdb 当前暂停所在的指令(源码中通过比较paused_addr === assm.address判断并应用current_assembly_command样式)。
如果源码文件找不到,gdbgui 会退化为纯汇编视图(见 screenshots/assembly.png),你仍然可以按需求单步执行每条指令。这一点在 gdbgui/src/js/SourceCode.tsx 的source_code_state状态机中体现:ASSM_CACHED(仅缓存到汇编)、FETCHING_ASSM、ASSM_UNAVAILABLE、FILE_MISSING等状态分别对应“仅汇编可显示”“正在拉取汇编”“无法访问地址”“文件未找到”等场景;汇编行会展示地址、操作码(如mov)、指令、函数名与偏移量(如main+8)。
变量与表达式:Locals、Hover、进制切换、XY 曲线与树视图
局部变量自动展示
程序暂停时,所有局部变量会自动显示(见 screenshots/locals.png),并且可以点击展开探索其字段。GdbVariable.get_ul_for_local()会渲染 gdb 返回的 local 对象,可展开的变量以+前缀提示,点击后通过-var-create创建完整变量对象供深入探索(见 gdbgui/src/js/GdbVariable.tsx)。
悬停探索变量
将鼠标悬停在变量上即可展开探索,体验类似 Chrome 调试器(见 screenshots/hover.png)。GdbVariable维护了ChildVarFetcher队列,通过-var-list-children --all-values串行拉取子变量;悬停(expr_type === "hover")失败时静默处理,不会打扰控制台。
任意表达式求值与进制切换
你还可以求值任意表达式(见 screenshots/expressions.png),这些表达式在单步执行过程中持续存在并自动刷新。在 gdbgui/src/js/Expressions.tsx 中,输入框回车后调用GdbVariable.create_variable(expr, "expr")创建表达式变量;同时通过-var-update --all-values在每次步进后更新值,并自动清理已失效(in_scope === "invalid")的变量。
表达式的基数(radix)可以按需修改(见 screenshots/radix.gif):GdbVariable.change_radix()会在 16(十六进制)→ 2(二进制)→ … 之间递增切换,并在 2~36 之间做防御性校验,切换后数值立即以新进制重新显示(见 gdbgui/src/js/GdbVariable.tsx 中的_update_radix_values)。
表达式历史与 XY 曲线
每个表达式都会记录其历史取值,并可切换为x/y 折线图展示数值随时间(步进次数)的变化(见 screenshots/plots.png)。GdbVariable._make_plot()使用 Flot 绘制曲线:数值型表达式(is_numeric && expr_type === "expr")会累积values数组,开启绘图后每个新值追加一个数据点,并支持悬停显示坐标(x, y)。
树形视图
表达式还可以在树形视图中交互式展开探索(见 screenshots/tree_explorer.png)。点击变量旁的树形图标会调用GdbVariable.click_draw_tree_gdb_variable(),将变量设为树根,用于大规模复杂数据结构的浏览。此外每个变量还提供复制完整路径(CopyToClipboard)与删除表达式(-var-delete)等操作。
内存查看器
内存查看器(见 screenshots/memory.png)具备以下特性:
- 所有十六进制地址都会被自动转换成可点击的链接,点击即可跳转到该地址探索内存内容;
- 内存长度可配置;
- 每行显示的字节数可配置(截图中为每行 10 字节)。
实现位于 gdbgui/src/js/Memory.tsx:界面提供start address (hex)、end address (hex)、bytes per line (dec)三个输入框,回车后通过-data-read-memory-bytes逐字节拉取数据并缓存。其内置默认值为DEFAULT_BYTES_PER_LINE = 8、DEFAULT_ADDRESS_DELTA_BYTES = 31,并设定了单次最多读取MAX_ADDRESS_DELTA_BYTES = 1000字节的上限——若请求范围超限会自动收窄并提示。表头为address / hex / char三列:十六进制值同时换算为可读字符(不可打印字符显示为.);表格顶部与底部各有一个more按钮,分别向前/向后按 3 行批量扩展读取范围。地址链接化通过make_addrs_into_links_react()用正则0x[\d\w]+匹配实现,Registers、Threads、SourceCode等组件均复用了这一能力。
寄存器视图
寄存器面板(见 screenshots/registers.png)会展示所有寄存器,且发生变化的寄存器会以黄色高亮显示。
gdbgui/src/js/Registers.tsx 的实现要点:
- 通过
-data-list-register-names获取寄存器名(只在首次获取,缓存于 store),通过-data-list-register-values x拉取全部寄存器当前值; - 表格包含四列:name、value (hex)、value (decimal)、description;十六进制值会自动转换为可点击的内存链接,并同时给出十进制换算;
- 将当前值与上一次值比较,发生变化的寄存器在名称、十六进制值、十进制值三处同时应用
highlight bold样式; - 寄存器名与描述来自 gdbgui/src/js/register_descriptions.ts;仅当被调试程序处于
paused状态时才渲染数据,程序退出时会清空缓存。
gdb 控制台
内置的 gdb 控制台(见 screenshots/console.png)具备以下能力(见 docs/screenshots.md):
- 打印 gdb 输出;
- 允许你直接向底层 gdb 子进程写入命令,如同在终端里使用 gdb 一样;
- 支持 Tab 键补全,并提供一个按钮查看 gdb 命令的帮助;
- 可以作为学习 gdb 的入门途径;
- 可以作为没有对应 UI 控件的命令的兜底手段;
- 支持用上/下方向键翻阅历史命令。
前端在 gdbgui/src/js/GdbApi.tsx 中通过send_autocomplete_command()发送 gdb 的complete命令实现补全;发送命令时会校验输入、更新控制台与状态栏,并可通过设置项决定是否把 gdbgui 自身发出的命令也显示在控制台中(show_all_sent_commands_in_console)。
认证:公网访问时启用 HTTP Basic Auth
当 gdbgui运行在可被公开访问的 IP 地址上时,可以启用认证保护(见 screenshots/authentication.png)。具体启用方式参见gdbgui --help中的说明。
从 gdbgui/cli.py 的源码可以确认,认证采用HTTP Basic Auth,相关命令行参数为:
--auth-file:指定一个文件,第一行是用户名、第二行是密码,用于认证;--user/--password:直接以命令行方式提供用户名与密码;- 二者不能同时使用(同时提供会报错),认证凭据最终注入
app.config["gdbgui_auth_user_credentials"]。
此外,当服务器对外公开且未配置认证时,gdbgui 会在启动时打印警告,提示公开服务建议启用认证(见 gdbgui/cli.py 中get_gdbgui_auth_user_credentials与相关启动逻辑)。
Dashboard:多实例管理与多人协同调试
gdbgui 的Dashboard(仪表盘)(见 screenshots/dashboard.png)用于查看由 gdbgui 管理的所有 gdb 实例,并允许:
- kill(终止)某个实例;
- attach(附加)到某个实例;
- 多人同时附加到同一个被管理的 gdb 子进程,共同参与同一个调试会话——例如某人执行一步前进,所有已连接的用户都会实时看到程序前进一步。
从后端结构看,gdb 实例的管理逻辑集中在 gdbgui/server/sessionmanager.py,gdbgui 作为中间层同时维护多个 gdb 子进程,并通过 WebSocket 把 gdb 的 MI 输出广播给所有订阅该会话的浏览器标签页,这正是多人实时同步的底层机制;gdbgui/server/ptylib.py 则负责与 gdb 子进程进行伪终端(pty)交互。
在 gdbgui 中验证这些功能
上面介绍的每个面板都来自真实运行的界面,你可以在本地快速复现。安装并启动 gdbgui 后(参考 docs/installation.md),用仓库自带的示例程序体验:
# 以 C 示例为例:编译并启动调试 cd examples/c make # 生成 hello 等可执行文件 gdbgui # 启动后浏览器自动打开调试界面然后在“加载二进制与参数”输入框中填写hello(或带路径的可执行文件),即可依次尝试:Run 运行、Next/Step 单步、点击行号设置断点、在表达式输入框求值并切换进制、悬停查看变量字段、点击十六进制地址进入内存查看器,以及在控制台直接输入bt、info registers等原生 gdb 命令。对于 Rust 示例,examples/rust/compile_and_debug.sh 提供了编译与调试的一体化脚本,可作参考。
小结
从 docs/screenshots.md 的功能总览可以看出,gdbgui 并非简单地把 gdb 输出“搬到”浏览器,而是围绕 GDB/MI 协议构建了一套完整、可点击、可交互的调试前端:执行控制、断点管理、栈与线程导航、变量/表达式观测(含进制切换、历史曲线与树视图)、内存/寄存器查看、原生 gdb 控制台、信号发送、认证保护与多实例多人协同。每一类界面操作都能在 gdbgui/src/js 的前端组件与 gdbgui/server 的后端会话管理中对应到具体实现,这也让 gdbgui 非常适合作为学习浏览器端调试器设计、或快速搭建图形化 GDB 工作流的参考实现。
- 开发工具
【免费下载链接】gdbgui
Browser-based frontend to gdb (gnu debugger). Add breakpoints, view the stack, visualize data structures, and more in C, C++, Go, Rust, and Fortran. Run gdbgui from the terminal and a new tab will open in your browser.
相关推荐
【亲测免费】 gdbgui - 浏览器版GDB调试器教程
gdbgui 浏览器版GDB调试器教程 1. 项目介绍 gdbgui 是一个基于Web的GDB前端,它为流行的开源调试器GDB提供了友好的图形用户界面。支持多种
开发工具揭秘AllTools核心功能:从PE文件分析到内核监控的全方位工具集
揭秘AllTools核心功能:从PE文件分析到内核监控的全方位工具集 AllTools是一套功能全面的系统工具集,集成了从PE文件分析到内核监控的各类实用工具,
全景视界终极指南:10个View360全景浏览器核心功能深度解析
View360全景浏览器是一款功能强大的360度全景图像和视频浏览解决方案,专为现代Web应用设计。作为egjs生态系统的重要组成部分,它提供了沉浸式的全景体验
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考