EpicGames/raddebugger
摘要
Epic Games 开源了 RAD Debugger——一款原生 Windows 用户模式图形调试器,同时开源了 RAD Debug Info(RDI)格式以及高性能 RAD Linker,后者面向 x64 PE/COFF 二进制文件,针对拥有数 GB 级调试信息的超大型项目进行了优化。
查看缓存全文
缓存时间: 2026/10/08 11:57
EpicGames/raddebugger
Source: https://github.com/EpicGames/raddebugger
RAD Debugger 项目
注意: 本 README 不包含调试器本身的使用说明与技巧,仅作为本项目的技术概述。调试器的 README(包含使用说明与技巧)会随调试器发布包一同提供,或在本地完成构建后位于 build 文件夹中。你可以在此处找到预构建的发布版本二进制文件。
RAD Debugger 是一个原生(native)、用户态(user-mode)、多进程的图形化调试器。目前仅支持在本地 Windows x64 上配合 PDB 进行调试,未来计划扩展并进行移植。未来我们将扩展到支持原生 Linux 调试以及 DWARF 调试信息。
调试器目前处于 ALPHA(早期测试) 阶段。为了让调试器达到足够健壮,如果你在此提交发现的问题(https://github.com/EpicGames/raddebugger/issues)并附上你所能收集到的信息(例如转储文件、复现步骤、测试用可执行文件等),将会非常有帮助。
除了调试器之外,我们还希望通过另外两项相关技术进一步完善工具链:(1) RAD Debug Info(RDI)格式,以及 (2) RAD Linker。
RAD Debug Info(RDI)格式
RAD Debug Info(RDI)格式是我们自定义的调试信息格式,调试器解析并使用它,而不是工具链原生生成的调试信息(如 PDB 或 DWARF)。为了与这些现有工具链配合工作,我们会按需将 PDB(以及将来嵌入 DWARF 的 PE/ELF 文件)转换为 RDI 格式。
RDI 格式目前在代码中以规范形式定义,具体位于 src/lib_rdi 文件夹中的文件里。在 rdi.h 和 rdi.c 中,定义了描述该格式本身的类型与函数;在 rdi_parse.h 和 rdi_parse.c 中,包含了用于解析该格式的辅助代码。
我们还有一个正在开发中的库,用于构造和序列化 RDI 数据,位于 src/lib_rdi_make 文件夹中。
我们的 radbin 工具(也可以通过调试器使用,即 --bin 命令行参数)能够将原生调试信息格式转换为 RDI,也能够生成 RDI 文件中所存储内容的文本转储。
RAD Linker
RAD Linker 是一款新的高性能链接器,用于生成 x64 PE/COFF 二进制文件。它在构建体量巨大的可执行文件时设计得非常快速。它会为调试生成标准的 PDB 文件,同时也可以(可选地)原生生成 RAD Debug Info——这不仅在调试时可以消除按需转换所需的时间,对于会产生 PDB 内部 32 位表溢出而导致损坏的巨型可执行文件来说也同样有用。
RAD Linker 主要针对处理超大型链接项目进行了优化。在我们的测试用例中(调试信息达到数 GB 规模),链接时间快了 50%。其命令行语法与 MSVC 完全兼容;你可以通过 /help 查看已实现开关的完整列表。
我们目前为该链接器设计的主要使用场景,是帮助处理巨型项目的「编译-调试」循环。我们暂时尚未支持链接时优化(link-time-optimizations),但该功能已在路线图上。
默认情况下,链接器会生成与核心数相同数量的线程,因此如果你计划并行运行多个链接器,可以通过 /rad_workers 限制工作线程的数量。我们还支持大页内存(large pages),启用后可以再将链接时间缩短约 25%。要使用大页进行链接,你需要通过 /rad_large_pages 明确请求。大页默认是关闭的,因为 Windows 对大页的支持存在一些缺陷;我们建议只在每次链接后环境会被重置的 Docker 或虚拟机镜像中使用大页。在标准 Windows 环境中使用大页会迅速造成内存碎片化,最终可能需要重启。
我们正在对链接器进行 Linux 移植,使其能够健壮地使用大页构建。链接器性能基准测试如下:
AMD Ryzen Threadripper PRO 3995WX 64-Core,256 GiB RAM(Windows x64)
项目开发环境搭建 / 本地构建说明
项目正在 Windows x64 和 Linux x64 开发机上同时进行积极开发。点击你想要使用的平台。
Windows x64
1. 安装所需工具(MSVC 与 Windows SDK)
首先,你需要安装 Microsoft C/C++ Build Tools v15(2017)或更高版本(https://aka.ms/vs/17/release/vs_BuildTools.exe),以获得 Windows SDK 以及 MSVC 编译器和链接器。如果已安装 Windows SDK(例如通过安装 Microsoft C/C++ Build Tools),你也可以使用 Clang(https://releases.llvm.org/)进行构建。
2. 构建环境设置
构建代码库可以在能够从命令行调用 MSVC 或 Clang 的终端中完成。这通常通过调用 vcvarsall.bat x64 来实现,该脚本包含在 Microsoft C/C++ Build Tools 中。原生 cmd.exe 的 x64 Native Tools Command Prompt for VS 变体会自动调用此脚本。
如果你安装了构建工具,可以在 Windows 开始菜单搜索中搜索 Native 来轻松找到这个命令提示符。
你可以运行以下命令来确认 MSVC 编译器可以从命令行访问:
cl
如果一切设置正确,你应该看到与以下内容非常相似的输出:
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30151 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
3. 构建
在此终端中,cd 到代码库的根目录,然后直接运行 build.bat 脚本:
build
你应该会看到如下输出:
[debug mode]
[msvc compile]
[default mode, assuming `raddbg` build]
metagen_main.c
searching C:\devel\raddebugger/src...
458 files found
parsing metadesk...
16 metadesk files parsed
gathering tables...
97 tables found
generating layer code...
raddbg_main.c
如果一切正常,代码库根目录下会生成一个 build 文件夹,其中包含新构建的 raddbg.exe。这个 raddbg.exe 是以 debug 模式 构建的,未启用优化,性能可能较差。
要生成 release 模式 的可执行文件,请运行 build.bat 并加上 release 参数:
build release
此次构建所需时间会显著更长。默认情况下,build.bat 在没有参数(或只有 release)时仅构建调试器,但你可以传入额外参数来构建 RAD Linker 或 radbin CLI 二进制文件工具:
build radlink release
build radbin release
Linux x64
1. 安装所需工具(GCC 或 Clang、库)
首先,如果你还没有 GCC 或 Clang,需要安装其中之一。可以根据你的发行版和所选工具链运行以下命令来获取:
Ubuntu / Debian / Mint 上的 GCC
sudo apt update && sudo apt install build-essential
Ubuntu / Debian / Mint 上的 Clang
sudo apt update && sudo apt install clang llvm
Arch / Manjaro 上的 GCC
sudo pacman -S base-devel
Arch / Manjaro 上的 Clang
sudo pacman -S clang llvm
如果你已安装所需的 Clang 和 LLVM 工具,可以运行:
clang --version && llvm-ar --version
你应该看到类似以下的输出:
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Ubuntu LLVM version 18.1.3
Optimized build.
如果你已安装所需的 GCC 工具,可以运行:
gcc --version && gcc-ar --version
你应该看到类似以下的输出:
gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU ar (GNU Binutils for Ubuntu) 2.42
Copyright (C) 2024 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of the
GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.
2. 安装依赖
调试器项目依赖系统中存在若干动态链接库:
libfreetypelibx11libxextlibxfixeslibxrandrlibgllibegl
构建时需要它们的开发包。可以根据你的发行版使用以下命令之一进行安装:
Ubuntu / Debian / Mint
sudo apt install -y libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxrandr-dev libgl-dev libegl-dev
Arch / Manjaro
sudo pacman -S --needed freetype2 libx11 libxext libxfixes libxrandr libglvnd
3. 构建
要进行构建,cd 到代码库的根目录,然后运行 build.sh 脚本:
./build.sh
你应该看到类似如下的输出:
[clang compile]
[debug mode]
[building metagen]
searching /mnt/c/devel/raddebugger/src...
562 files found
parsing metadesk...
23 metadesk files parsed
gathering tables...
138 tables found
generating layer code...
如果一切正常,代码库根目录下会生成一个 build 文件夹,其中包含新构建的 raddbg 二进制文件。这个 raddbg 是以 debug 模式 构建的,未启用优化,性能可能较差。
要生成 release 模式 的可执行文件,请运行 build.sh 并加上 release 参数:
./build.sh release
此次构建所需时间会显著更长。默认情况下,build.sh 在没有参数(或只有 release)时仅构建调试器,但你可以传入额外参数来构建 RAD Linker 或 radbin CLI 二进制文件工具:
./build.sh radlink release
./build.sh radbin release
项目路线图
初始 Alpha 实战检验阶段
项目的第一优先级是确保最关键的组件在本地 x64 Windows 开发环境中运行得极其可靠。对于调试器而言,这包括调试信息转换、调试信息加载、进程控制、单步执行、求值(正确使用位置信息与类型信息),以及一个健壮的前端,确保底层部分能够真正可用。对于链接器而言,则关乎可靠性以及与现有链接器行为的一致性。
我们认为这些方面已经取得了长足进展,但由于语言、构建设置、工具链、所用语言特性以及生成代码模式的组合数量极其庞大,我们仍预期会遇到一些问题,并将优先解决这些问题。
我们还希望在这一阶段继续改进性能。对于调试器,这主要包括前端性能、在合适之处引入缓存,以及对现有系统的优化与收紧。对于链接器,目前的调校主要面向巨型项目,因此我们同样希望改进中小型项目的链接速度。
对于链接器,还有若干功能即将推出,例如死代码消除(/opt:ref),以及借助 clang 实现的链接时优化(我们不会支持 MSVC 的 LTCG,因为其未公开文档)。
本地 x64 Linux 调试阶段
项目的下一优先级是将目前坚如磐石的 x64 Windows 调试体验,把所有相关部分移植过来,以支持本地 x64 Linux 调试。调试器在编写时已经对需要在 Linux 或 Windows 上有所不同的部分做了抽象,因此这一阶段的主要任务是为这些抽象层构建不同的后端实现。
本阶段的主要内容包括:
- 移植
src/demon层,以实现 Demon 本地进程控制抽象 API。 - 在
src/ctrl层实现面向 x64 ELF Linux 的栈回溯器(unwinder)。 - 创建 DWARF-to-RDI 转换器(与我们构建 PDB-to-RDI 转换器的方式相同)。其中一部分实现已位于
src/rdi_from_dwarf。 - 移植
src/render层,在兼容 Linux 的 API 上实现前端所需的全部渲染功能(Windows 上使用的后端为 D3D11)。 - 将
src/font_provider层移植到兼容 Linux 的字体光栅化后端(例如 FreeType;Windows 上使用的后端为 DirectWrite)。 - 将
src中的os层移植到 Linux。这包括核心操作系统抽象(虚拟内存分配、线程与同步原语等)以及图形操作系统抽象(窗口、输入事件等)。
一旦上述列表完成,且每一部分都变得坚如磐石,我们一直努力打造的 Windows 调试体验也将能够原生地在 Linux 机器上使用。
更长远的方向!
在这两个主要阶段之后,我们还有多个可能的方向,例如远程调试、移植到不同的体系架构、进一步改进调试器的功能(如改进可视化引擎)等等。不过目前,我们主要专注于上述前两个阶段。
代码库简介
顶层目录说明
data:构建时使用的小型二进制文件,要么嵌入到构建产物中,要么与构建产物一同打包。src:全部源代码。
完成代码库搭建并构建后,还会存在以下目录:
build:全部构建产物。不纳入版本控制。local:本地文件,用作本地构建配置的输入文件。不纳入版本控制。
层(Layer)说明
代码库由若干 层(layer) 组成。层与层之间相互隔离,以便把某些代码引入各种构建中,而无需将代码库的全部内容一并拉入构建。层对应 src 目录内部的文件夹。有时 src 目录下的一个文件夹会包含多个子层,但整体结构有意保持得相当扁平。
层大致与 命名空间(namespace) 一一对应。此处所说的「命名空间」并非指某种特定的语言命名空间特性,而是一种 C 风格命名空间的命名约定:在代码库中写成一个简短前缀(通常 1 到 3 个字符)后跟一个下划线。使用这些命名空间,可以让人通过一眼浏览代码就迅速明白某段代码属于哪个层。
命名空间通常非常简短,以确保书写起来不怎么麻烦。有时多个子层会共享同一个命名空间。少数层没有命名空间,但大多数层都有。
命名空间根据其使用场景的不同,或全大写,或全小写。对于类型、枚举值以及部分宏,采用首字母大写;对于函数和全局变量,采用全小写。
层会依赖其他层,但循环依赖会破坏层的可分离性与隔离效用(实际上等于把它们合并成了一个大层),换句话说,层被组织成一个有向无环图(DAG)。
少数层被设计为可完全独立于代码库其余部分使用,作为其他代码库和项目中的库。因此,这些层不依赖代码库中的任何其他层。包含这些层的文件夹以 lib_ 作为前缀,例如 lib_rdi。
以下列出了代码库中的各层及其关联的命名空间:
artifact_cache(AC_):实现一个按需异步填充的计算产物缓存,在不再被访问时会自动淘汰。用于异步流式传输与缓存进程内存和文件系统内容,以及异步准备……
相似文章
展示 HN:我为 Windows 原生 x64/x86 崩溃构建了一个事后调试器
ForensicDbg 是一个现代化的事后调试器,专为 Windows 原生 x64/x86 崩溃设计,具备集成AI的MCP接口和最先进的用户界面,以实现高效的错误识别和分析。
@mylifcc:逆向工程正在彻底改变……刚试了 GitHub 上这个宝藏开源项目:x64dbg-mcp-server,把……
x64dbg-mcp-server 是一个开源项目,它将 Windows 调试器 x64dbg 封装为 MCP 服务,让 Claude 等 AI 助手可以直接操控调试过程——设置断点、单步执行、提取解密后的字符串——同时提供 80 多个调试 API,整个项目用 Zig 纯原生编写,零依赖。
从零编写调试器
本文开启了一个使用Rust从零构建调试器的系列,首先介绍如何使用操作系统调试API附加到Windows进程。
被低估的内置功能:Grand Unified Debugger
本文重点介绍了Emacs内置的Grand Unified Debugger(GUD)的功能,强调了其多调试器支持和图形化GDB界面,包括通过点击边缘设置断点以及单步执行代码等功能。
破解Windows:将RADV移植到Win32
Collabora 报告了将面向 AMD GPU 的开源 RADV Vulkan 驱动从 Linux 移植到 Windows 的过程,通过逆向工程 WDDM2 接口成功运行了 Counter-Strike 2。