Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

调试器属性

以下 属性 用于在使用 GDB 或 WinDbg 等第三方调试器时增强调试体验。

debugger_visualizer属性

debugger_visualizer 属性 可用于将调试器可视化工具文件嵌入到调试信息中。这改进了显示值时的调试器体验。

例子

#![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 的框架,适用于 Microsoft 调试器(如 Visual Studio 和 WinDbg),它使用声明性规则来自定义类型的显示。有关 Natvis 格式的详细信息,请参阅 Microsoft 的 Natvis 文档

此属性仅支持在 -windows-msvc 目标上嵌入 Natvis 文件。

Natvis 文件的路径由 natvis_file 键指定,该路径是相对于源文件的路径。

例子

#![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!("在此设置断点");
}

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,它描述了类型应如何在调试器视图中可视化。有关 pretty printer 的详细信息,请参阅 GDB 的 pretty printing 文档

注意

在 GDB 下调试二进制文件时,嵌入式 pretty printer 不会自动加载。

有两种方法可以启用自动加载嵌入式 pretty printer:

  1. 启动 GDB 时带上额外参数,以显式添加目录或二进制文件到自动加载安全路径:gdb -iex "add-auto-load-safe-path safe-path path/to/binary" path/to/binary。有关更多信息,请参阅 GDB 的 auto-loading 文档
  2. $HOME/.config/gdb 下创建一个名为 gdbinit 的文件(如果目录不存在,您可能需要创建它)。在该文件中添加以下行:add-auto-load-safe-path path/to/binary

这些脚本使用 gdb_script_file 键嵌入,该键是相对于源文件的路径。

例子

#![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!("在此设置断点");
}

printer.py 包含:

import gdb

class PersonPrinter:
    "打印一个 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 属性 控制在为调用此宏的代码生成调试信息时,是否将来自宏定义的代码位置折叠到与宏的调用点关联的单个位置。

例子

#![allow(unused)]
fn main() {
#[collapse_debuginfo(yes)]
macro_rules! example {
    () => {
        println!("你好!");
    };
}
}

当使用调试器时,调用 example 宏可能看起来像是调用一个函数。也就是说,当您单步执行到调用点时,它可能会显示宏调用而不是展开的代码。

collapse_debuginfo 属性的 语法格式 是:

Syntax
CollapseDebuginfoAttributecollapse_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

注意

rustc 有一个 -C collapse-macro-debuginfo CLI 选项,可以覆盖默认行为以及任何 #[collapse_debuginfo] 属性的值。


  1. 注意:这假设您正在使用 rust-gdb 脚本,该脚本为 String 等标准库类型配置了 pretty printer。