Natvis 扩展至 Linux 和 macOS:无需编写数据格式化器即可可视化 C++ 类型
如果你曾需要在 Linux 或 macOS 上调试自己的 C++ 容器、字符串或哈希表,你一定知道是怎么回事:要想在调试器中看到有用的信息,就得编写自定义数据格式化器。而编写一个优秀的数据格式化器确实令人痛苦。通常,格式化器比它要解释的类本身更长、更难维护。
从 Rider 2026.2 开始,你再也不需要这样做了。Natvis 现在不仅支持 Windows,也适用于 Linux 和 macOS。你只需用几行 XML 描述类型在调试器中的展示方式,剩下的工作就由 Rider 的调试器来完成。
让我们来看看这为什么重要。
一个类,以及它应得的格式化器
下面是一个简单的栈。没什么特别的——包含大小、容量和一个指向数据的指针:
让我们添加一些元素,看看调试器会显示什么。
默认情况下,调试器会显示类似这样的内容: [LOADING...]
你看到大小、容量,以及正好一个元素。另外两个元素在内存中的某个地方,但调试器并不知道它们的存在。
要查看整个栈,你需要一个数据格式化器。它看起来像这样……🫠
点击此处展开——你已经看够了,现在可以关闭了。
这就是大约 70 行 Python 代码,用来解释一个长度也差不多的类。将其加载到 LLDB 后,调试器终于显示了所有内容: [LOADING...]
它能工作,但代价是什么?你现在拥有并维护一个比它描述的类型更难读的格式化器——而且这只是针对一个类。如果将其乘以一个真实项目中几十个类型,情况很快就会变得糟糕。
Natvis 来拯救
如果你在 Windows 上使用 MSVC 工具链构建,那么这些都不是新闻——Natvis 是那里可视化类型的标准方式,Rider 和 CLion 已经支持多年了。全新的地方在于,同样的文件现在也可以在 Linux 和 macOS 上工作。你已经拥有的 Natvis 现在可以在更多地方使用。
看看 MyStack<T> 的 Natvis 有多么简单和容易:
更容易了,对吧?只需要一点点 XML。
如果你用这个 Natvis 运行调试会话,你会看到: [LOADING...]
完全相同(加上 Raw View,但你可以随时使用 HideRawView 属性将其删除)!
Natvis 可以描述什么
上面的栈使用了 <ArrayItems>,但这只是众多工具之一。Natvis 涵盖了大多数你实际编写的数据结构:
- <ArrayItems> —— 连续数组和指针
- <IndexListItems> —— 紧凑或非连续内存中的类数组容器(
std::deque、std::bitset) - <LinkedListItems> —— 链表
- <TreeItems> —— 树结构
- <CustomListItems> —— 其他任何结构,包括哈希表,使用小表达式遍历结构
还有更多内容,请参考 官方 Natvis 文档 和 完整架构 以了解确切的合法元素。
如何启用
在 Linux 和 macOS 上使用 Natvis 需要三步:
- 使用 LLDB。 Natvis 只支持 LLDB。请前往 文件 | 设置 | 构建、执行、部署 | 工具链,确认调试器设置是 "Bundled LLDB"。
- 启用 Natvis 渲染。 默认情况下是关闭的。请前往 文件 | 设置 | 构建、执行、部署 | 调试器 | 数据视图 | C/C++,打开 为 LLDB 启用 Natvis 渲染器。
- 让 Rider 找到你的 Natvis 文件。 最简洁的方式是将它们添加到你的 CMake 项目中,既可以作为现有目标的源文件:
或者创建一个专门用于 Natvis 文件的自定义目标:
如果你不想修改 CMake,也可以在同一个 数据视图 | C/C++ 设置页面下的 附加目录 中添加一个文件夹。
如果一切设置正常但没有任何渲染,很可能是调试器遇到了 Natvis 文件中的语法错误并默默放弃了。打开 Natvis 诊断(同一个设置页面)并检查 调试器输出 (LLDB) 标签页——解析错误会显示在那里。
你可能已经在使用 Natvis
这并非一个需要从零开始的功能。很多 C++ 生态系统已经随附了 Natvis,尤其是在游戏开发领域:
- Godot 引擎 和 godot-cpp 扩展
- Flax 引擎
- JoltPhysics —— 物理和碰撞检测
- Box2D —— 2D 物理
- Dear ImGui —— 即时模式 GUI
- Bgfx —— 跨平台渲染
- EnTT —— 实体组件系统
- Magnum —— 游戏和可视化数据图形中间件
如果你依赖其中任何一个,它们的可视化器现在在 Linux 和 macOS 上的 Rider 中会自动生效,无需你额外操作。
已经能用的和即将到来的
我们坦诚地说明一下边界。在底层,我们的 Natvis 支持本质上是一组高级的 LLDB 数据格式化器,它们解析你的 .natvis 文件,并大量依赖 LLDB 的表达式求值器来完成工作。
在 Windows 上,该求值器是我们自己的。我们维护了一个 LLDB 9 的自定义分支,带有数百个补丁,并且在 Rider 2026.1 中,我们从头重写了专门用于 Natvis 的表达式求值器——正是这项工作使虚幻引擎的变量检查速度提升了最多 87 倍。
在 Linux 和 macOS 上,我们使用的是上游 LLDB 21,这意味着这些改进尚未到位。这些操作系统上的 Natvis 使用的是标准的 LLDB 表达式求值器。
对于大多数类型来说,这没有问题。特殊情况是那些使用了最先进功能的 Natvis 文件,而虚幻引擎就是一个典型的例子:它的 Natvis 非常复杂,目前在 Linux 和 macOS 上还不能完美运行。将新的 Windows LLDB 9 求值器移植到 LLDB 21 已经在路线图上,但这需要大量工作。目前,欢迎你在这些平台上尝试虚幻引擎的 Natvis——只是要做好遇到一些边缘问题的准备。此外,现有的虚幻引擎 LLDB 数据格式化器在这些平台上仍然可用,因此如果你在虚幻引擎项目中启用 Natvis,两者会并行运行。
已经有自己的数据格式化器?保留它们。
如果你编写的 LLDB 数据格式化器对你来说工作良好,Natvis 不会干扰它们。Natvis 在任何用户自定义格式化器中优先级最低——只要你的某个格式化器已经处理了某个类型,Natvis 就不会干预。你可以逐步地、逐个类型地采用 Natvis,而无需丢弃任何东西。
试试看
Linux 和 macOS 上的 Natvis 在 Rider 2026.2 中可用。将其指向你已有的 Natvis 文件,切换上面讨论的两个设置,然后 watch 你的类型开始变得有意义。
下载 Rider