diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index 10c83a240..bdf1e181f 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -7,11 +7,27 @@ r[attributes.debugger.debugger_visualizer] ## The `debugger_visualizer` attribute r[attributes.debugger.debugger_visualizer.intro] -The *`debugger_visualizer` attribute* can be used to embed a debugger visualizer file into the debug information. +The *`debugger_visualizer` [attribute][attributes]* can be used to embed a debugger visualizer file into the debug information. This enables an improved debugger experience for displaying values in the debugger. +> [!EXAMPLE] +> +> ```rust,ignore +> #![debugger_visualizer(natvis_file = "Example.natvis")] +> #![debugger_visualizer(gdb_script_file = "example.py")] +> ``` + r[attributes.debugger.debugger_visualizer.syntax] -It uses the [MetaListNameValueStr] syntax to specify its inputs, and must be specified as a crate attribute. +The `debugger_visualizer` attribute uses the [MetaListNameValueStr] syntax to specify its inputs. One of the following keys must be specified: + +- [`natvis_file`][attributes.debugger.debugger_visualizer.natvis] +- [`gdb_script_file`][attributes.debugger.debugger_visualizer.gdb] + +r[attributes.debugger.debugger_visualizer.allowed-positions] +The `debugger_visualizer` attribute may only be specified on a [module] or crate root. + +r[attributes.debugger.debugger_visualizer.duplicates] +Duplicate instances of the `debugger_visualizer` attribute will load all of the specified visualizers. r[attributes.debugger.debugger_visualizer.natvis] ### Using `debugger_visualizer` with Natvis @@ -24,60 +40,61 @@ r[attributes.debugger.debugger_visualizer.natvis.msvc] This attribute only supports embedding Natvis files on `-windows-msvc` targets. r[attributes.debugger.debugger_visualizer.natvis.path] -The path to the Natvis file is specified with the `natvis_file` key, which is a path relative to the crate source file: - - -```rust ignore -#![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"); -} -``` - -and `Rectangle.natvis` contains: - -```xml - - - - ({x},{y}) + ({dx}, {dy}) - - - ({x}, {y}) - - - ({x}, {y + dy}) - - - ({x + dx}, {y + dy}) - - - ({x + dx}, {y}) - - - - -``` - -When viewed under WinDbg, the `fancy_rect` variable would be shown as follows: - -```text -> 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) -``` +The path to the Natvis file is specified with the `natvis_file` key, which is a path relative to the crate source file. + +> [!EXAMPLE] +> +> ```rust ignore +> #![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"); +> } +> ``` +> +> and `Rectangle.natvis` contains: +> +> ```xml +> +> +> +> ({x},{y}) + ({dx}, {dy}) +> +> +> ({x}, {y}) +> +> +> ({x}, {y + dy}) +> +> +> ({x + dx}, {y + dy}) +> +> +> ({x + dx}, {y}) +> +> +> +> +> ``` +> +> When viewed under WinDbg, the `fancy_rect` variable would be shown as follows: +> +> ```text +> > 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) +> ``` r[attributes.debugger.debugger_visualizer.gdb] ### Using `debugger_visualizer` with GDB @@ -95,56 +112,57 @@ There are two ways to enable auto-loading embedded pretty printers: r[attributes.debugger.debugger_visualizer.gdb.path] These scripts are embedded using the `gdb_script_file` key, which is a path relative to the crate source file. - -```rust ignore -#![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"); -} -``` - -and `printer.py` contains: - -```python -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) -``` - -When the crate's debug executable is passed into GDB[^rust-gdb], `print bob` will display: - -```text -"Bob" is 10 years old. -``` - -[^rust-gdb]: Note: This assumes you are using the `rust-gdb` script which configures pretty-printers for standard library types like `String`. +> [!EXAMPLE] +> +> ```rust ignore +> #![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"); +> } +> ``` +> +> and `printer.py` contains: +> +> ```python +> 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) +> ``` +> +> When the crate's debug executable is passed into GDB[^rust-gdb], `print bob` will display: +> +> ```text +> "Bob" is 10 years old. +> ``` +> +> [^rust-gdb]: Note: This assumes you are using the `rust-gdb` script which configures pretty-printers for standard library types like `String`. [auto-loading documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html [attributes]: ../attributes.md @@ -184,3 +202,4 @@ macro_rules! example { ``` [attribute]: ../attributes.md +[module]: ../items/modules.md