Атрибуты отладчика
Следующие атрибуты используются для улучшения опыта отладки при использовании сторонних отладчиков, таких как 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 может применяться только к модулю или к корню крейта.
Атрибут debugger_visualizer может использоваться любое количество раз на форме. Все указанные файлы визуализаторов будут загружены.
Использование debugger_visualizer с Natvis
Natvis — это основанный на XML фреймворк для отладчиков Microsoft (таких как Visual Studio и WinDbg), который использует декларативные правила для настройки отображения типов. Для подробной информации о формате Natvis обратитесь к документации Natvis от Microsoft.
Этот атрибут поддерживает встраивание файлов Natvis только для целей -windows-msvc.
Путь к файлу 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 (красивым принтером), который описывает, как тип должен визуализироваться в представлении отладчика. Для подробной информации о pretty printers обратитесь к документации по pretty printing от GDB.
Note
Встроенные pretty printers не загружаются автоматически при отладке бинарного файла под GDB.
Есть два способа включить автозагрузку встроенных pretty printers:
- Запустить GDB с дополнительными аргументами для явного добавления директории или бинарного файла в безопасный путь автозагрузки:
gdb -iex "add-auto-load-safe-path safe-path path/to/binary" path/to/binaryДля получения дополнительной информации см. документацию по автозагрузке GDB.- Создать файл с именем
gdbinitв$HOME/.config/gdb(возможно, вам потребуется создать директорию, если она ещё не существует). Добавьте следующую строку в этот файл: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)Когда отладочный исполняемый файл крейта передаётся в 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)]— Местоположения кода в отладочной информации сворачиваются только если макрос происходит из другого крейта.
Поведение external является значением по умолчанию для макросов, которые не имеют этого атрибута, за исключением встроенных макросов. Для встроенных макросов значением по умолчанию является yes.
Note
rustcимеет опцию CLI-C collapse-macro-debuginfoдля переопределения как поведения по умолчанию, так и значений любых атрибутов#[collapse_debuginfo].
-
Примечание: Это предполагает, что вы используете скрипт
rust-gdb, который настраивает pretty-printers для типов стандартной библиотеки, таких какString. ↩