调试器属性
以下属性用于增强使用第三方调试器(如 GDB 或 WinDbg)时的调试体验。
debugger_visualizer 属性
debugger_visualizer 属性 可用于将调试器可视化文件嵌入到调试信息中。这改善了显示值时的调试器体验。
Example
#![debugger_visualizer(natvis_file = "Example.natvis")] #![debugger_visualizer(gdb_script_file = "example.py")]
debugger_visualizer 属性使用 MetaListNameValueStr 语法来指定其输入。必须指定以下键之一:
debugger_visualizer 属性只能应用于模块或 crate 根。
debugger_visualizer 属性可以在一个形式上使用任意次数。所有指定的可视化文件都将被加载。
将 debugger_visualizer 与 Natvis 一起使用
Natvis 是一个基于 XML 的框架,适用于微软调试器(如 Visual Studio 和 WinDbg),使用声明式规则来自定义类型的显示。有关 Natvis 格式的详细信息,请参考微软的 Natvis 文档。
此属性仅支持在 -windows-msvc 目标上嵌入 Natvis 文件。
Natvis 文件的路径通过 natvis_file 键指定,该路径是相对于源文件的路径。
Example
#![debugger_visualizer(natvis_file = "Rectangle.natvis")] struct FancyRect { x: f32, y: f32, dx: f32, dy: f32, } fn main() { let fancy_rect = FancyRect { x: 10.0, y: 10.0, dx: 5.0, dy: 5.0 }; println!("set breakpoint here"); }
Rectangle.natvis包含:<?xml version="1.0" encoding="utf-8"?> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <Type Name="foo::FancyRect"> <DisplayString>({x},{y}) + ({dx}, {dy})</DisplayString> <Expand> <Synthetic Name="LowerLeft"> <DisplayString>({x}, {y})</DisplayString> </Synthetic> <Synthetic Name="UpperLeft"> <DisplayString>({x}, {y + dy})</DisplayString> </Synthetic> <Synthetic Name="UpperRight"> <DisplayString>({x + dx}, {y + dy})</DisplayString> </Synthetic> <Synthetic Name="LowerRight"> <DisplayString>({x + dx}, {y})</DisplayString> </Synthetic> </Expand> </Type> </AutoVisualizer>在 WinDbg 下查看时,
fancy_rect变量将显示如下:> Variables: > fancy_rect: (10.0, 10.0) + (5.0, 5.0) > LowerLeft: (10.0, 10.0) > UpperLeft: (10.0, 15.0) > UpperRight: (15.0, 15.0) > LowerRight: (15.0, 10.0)
将 debugger_visualizer 与 GDB 一起使用
GDB 支持使用结构化 Python 脚本,称为美化打印器(pretty printer),来描述类型在调试器视图中应该如何显示。有关美化打印器的详细信息,请参考 GDB 的美化打印文档。
Note
在 GDB 下调试二进制文件时,嵌入的美化打印器不会自动加载。
有两种方法可以启用自动加载嵌入的美化打印器:
- 使用额外参数启动 GDB,显式地将目录或二进制文件添加到自动加载安全路径:
gdb -iex "add-auto-load-safe-path safe-path path/to/binary" path/to/binary。有关更多信息,请参见 GDB 的自动加载文档。- 在
$HOME/.config/gdb下创建一个名为gdbinit的文件(如果目录尚不存在,可能需要创建)。将以下行添加到该文件:add-auto-load-safe-path path/to/binary。
这些脚本使用 gdb_script_file 键嵌入,该路径是相对于源文件的路径。
Example
#![debugger_visualizer(gdb_script_file = "printer.py")] struct Person { name: String, age: i32, } fn main() { let bob = Person { name: String::from("Bob"), age: 10 }; println!("set breakpoint here"); }
printer.py包含:import gdb class PersonPrinter: "Print a Person" def __init__(self, val): self.val = val self.name = val["name"] self.age = int(val["age"]) def to_string(self): return "{} is {} years old.".format(self.name, self.age) def lookup(val): lookup_tag = val.type.tag if lookup_tag is None: return None if "foo::Person" == lookup_tag: return PersonPrinter(val) return None gdb.current_objfile().pretty_printers.append(lookup)当 crate 的调试可执行文件传递给 GDB1 时,
print bob将显示:"Bob" is 10 years old.
collapse_debuginfo 属性
collapse_debuginfo 属性 控制在为调用此宏的代码生成调试信息时,是否将宏定义中的代码位置折叠为与宏调用点关联的单个位置。
Example
#![allow(unused)] fn main() { #[collapse_debuginfo(yes)] macro_rules! example { () => { println!("hello!"); }; } }在使用调试器时,调用
example宏可能看起来像是调用一个函数。也就是说,当你步进到调用点时,它可能显示宏调用而不是展开的代码。
collapse_debuginfo 属性的语法如下:
Syntax
CollapseDebuginfoAttribute → collapse_debuginfo ( CollapseDebuginfoOption )
CollapseDebuginfoOption →
yes
| no
| external
collapse_debuginfo 属性只能应用于 macro_rules 定义。
collapse_debuginfo 属性在一个宏上只能使用一次。
collapse_debuginfo 属性接受以下选项:
#[collapse_debuginfo(yes)]— 调试信息中的代码位置被折叠。#[collapse_debuginfo(no)]— 调试信息中的代码位置不被折叠。#[collapse_debuginfo(external)]— 仅当宏来自不同的 crate 时,调试信息中的代码位置才被折叠。
对于没有此属性的宏,external 行为是默认的,除非它们是内置宏。对于内置宏,默认是 yes。
Note
rustc有一个-C collapse-macro-debuginfoCLI 选项,可以覆盖默认行为以及任何#[collapse_debuginfo]属性的值。
-
注意:这假设你使用
rust-gdb脚本,该脚本为像String这样的标准库类型配置了美化打印器。 ↩