From 2749bce8307f4801d818b7697f38f34376a67d19 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Mon, 27 Feb 2023 13:24:43 -0800 Subject: [PATCH 01/10] first pass for debugger_visualizer docs --- src/attributes.md | 2 + src/attributes/diagnostics.md | 147 ++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/src/attributes.md b/src/attributes.md index 5d619c990..6cde0ac81 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -224,6 +224,7 @@ The following is an index of all built-in attributes. - [`allow`], [`warn`], [`deny`], [`forbid`] — Alters the default lint level. - [`deprecated`] — Generates deprecation notices. - [`must_use`] — Generates a lint for unused values. + - [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type - ABI, linking, symbols, and FFI - [`link`] — Specifies a native library to link with an `extern` block. - [`link_name`] — Specifies the name of the symbol for functions or statics @@ -291,6 +292,7 @@ The following is an index of all built-in attributes. [`cold`]: attributes/codegen.md#the-cold-attribute [`crate_name`]: crates-and-source-files.md#the-crate_name-attribute [`crate_type`]: linkage.md +[`debugger_visualizer`]: attributes/diagnostics.md#the-debugger_visualizer-attribute [`deny`]: attributes/diagnostics.md#lint-check-attributes [`deprecated`]: attributes/diagnostics.md#the-deprecated-attribute [`derive`]: attributes/derive.md diff --git a/src/attributes/diagnostics.md b/src/attributes/diagnostics.md index 506e2848b..1a8bd9f0e 100644 --- a/src/attributes/diagnostics.md +++ b/src/attributes/diagnostics.md @@ -301,7 +301,154 @@ When used on a function in a trait implementation, the attribute does nothing. > let _ = five(); > ``` +## The `debugger_visualizer` attribute + +The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the PDB/ELF generated by `rustc`. +This enables an improved debugger experience for types outside of Rust's standard library. + +### Using `debugger_visualizer` with Natvis + +Natvis is an XML-based framework, and a `.natvis` file declares how a type's fields should be displayed in the debugger view. +A Natvis file is embedded using the `natvis-file` meta item. +Microsoft's [Natvis documentation] can be referenced to help developers write their own `.natvis` files. + +
+Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets. +`-windows-gnu` targets are not currently supported. +
+ +Consider a crate with this directory structure: + +```text +/Cargo.toml +/Foo.natvis (Note: the Natvis file does not have to match the name of the crate.) + +-- src + +-- main.rs +``` + +Where `main.rs` contains: + +```rust +#![debugger_visualizer(natvis_file = "../Foo.natvis")] +struct FancyRect { + pub x: f32, + pub y: f32, + pub dx: f32, + pub dy: f32, +} + +fn main() { + let mut fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); +} +``` + +and `Foo.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, 10) + (5, 5) + > LowerLeft: (10, 10) + > UpperLeft: (10, 15) + > UpperRight: (15, 15) + > LowerRight: (15, 10) +``` + +### Using `debugger_visualizer` with GDB + +Developers using GDB are able to embed *pretty printers* onto types. +In GDB, a pretty printer is a structured Python script that describes how a type's fields should be displayed in the debugger view. +These scripts are embedded using the `gdb_script_file` meta item. +GDB's [pretty print documentation] can be referenced by developers to help them write their own `.py` scripts. + +Consider a crate with this directory structure: + +```text +/Cargo.toml +/bar.py (Note: the file does not have to match the name of the crate.) + +-- src + +-- main.rs +``` + +Where `main.rs` contains: + +```rust +#![debugger_visualizer(gdb_script_file = "../bar.py")] +mod person { + pub struct Person { + pub name: String, + pub age: i32, + } +} + +use person::Person; + +fn main() { + let person = Person::new(String::from("Bob"), 10); +} +``` + +and `bar.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 "main::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, `print person` should display: + +``` +"Bob" is 10 years old. +``` + [Clippy]: https://github.com/rust-lang/rust-clippy +[Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects +[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax [_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax From ed69dfa154a52f4999491b102d8ca64e65f3835b Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Tue, 28 Feb 2023 13:00:23 -0800 Subject: [PATCH 02/10] move to debugger page, modify style --- src/attributes.md | 5 +- src/attributes/debugger.md | 150 ++++++++++++++++++++++++++++++++++ src/attributes/diagnostics.md | 147 --------------------------------- 3 files changed, 153 insertions(+), 149 deletions(-) create mode 100644 src/attributes/debugger.md diff --git a/src/attributes.md b/src/attributes.md index 6cde0ac81..28d49fff1 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -224,7 +224,6 @@ The following is an index of all built-in attributes. - [`allow`], [`warn`], [`deny`], [`forbid`] — Alters the default lint level. - [`deprecated`] — Generates deprecation notices. - [`must_use`] — Generates a lint for unused values. - - [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type - ABI, linking, symbols, and FFI - [`link`] — Specifies a native library to link with an `extern` block. - [`link_name`] — Specifies the name of the symbol for functions or statics @@ -272,6 +271,8 @@ The following is an index of all built-in attributes. - Type System - [`non_exhaustive`] — Indicate that a type will have more fields/variants added in future. +- Debugger + - [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type [Doc comments]: comments.md#doc-comments [ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm @@ -292,7 +293,7 @@ The following is an index of all built-in attributes. [`cold`]: attributes/codegen.md#the-cold-attribute [`crate_name`]: crates-and-source-files.md#the-crate_name-attribute [`crate_type`]: linkage.md -[`debugger_visualizer`]: attributes/diagnostics.md#the-debugger_visualizer-attribute +[`debugger_visualizer`]: attributes/debugger.md#the-debugger_visualizer-attribute [`deny`]: attributes/diagnostics.md#lint-check-attributes [`deprecated`]: attributes/diagnostics.md#the-deprecated-attribute [`derive`]: attributes/derive.md diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md new file mode 100644 index 000000000..f3dcfcd58 --- /dev/null +++ b/src/attributes/debugger.md @@ -0,0 +1,150 @@ +# Debugger attributes + +The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. + +## The `debugger_visualizer` attribute + +The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the debug information generated by `rustc`. +This enables an improved debugger experience for types outside of Rust's standard library. + +### Using `debugger_visualizer` with Natvis + +Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg that uses declarative rules to customize the display of types. +A Natvis file is embedded using the `natvis-file` meta item. +For detailed information on the Natvis format, refer to Microsoft's [Natvis documentation]. + +
+Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets. +
+ +Consider a crate with this directory structure: + +```text +/Cargo.toml +/Rectangle.natvis + +-- src + +-- main.rs +``` + +Where `main.rs` contains: + +```rust +#![debugger_visualizer(natvis_file = "../Rectangle.natvis")] +struct FancyRect { + pub x: f32, + pub y: f32, + pub dx: f32, + pub dy: f32, +} + +fn main() { + let mut fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); +} +``` + +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, 10) + (5, 5) + > LowerLeft: (10, 10) + > UpperLeft: (10, 15) + > UpperRight: (15, 15) + > LowerRight: (15, 10) +``` + +### Using `debugger_visualizer` with GDB + +GDB supports the use of a structured Python script, called a *pretty printer*, that describes how a type should be visualized in the debugger view. +These scripts are embedded using the `gdb_script_file` meta item. +For detailed information on pretty printers, refer to GDB's [pretty print documentation]. + +Consider a crate with this directory structure: + +```text +/Cargo.toml +/person_printer.py + +-- src + +-- main.rs +``` + +Where `main.rs` contains: + +```rust +#![debugger_visualizer(gdb_script_file = "../bar.py")] +mod person { + pub struct Person { + pub name: String, + pub age: i32, + } +} + +use person::Person; + +fn main() { + let person = Person::new(String::from("Bob"), 10); +} +``` + +and `person_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 "person::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, `print person` will display: + +``` +"Bob" is 10 years old. +``` + +[attributes]: ../attributes.md +[Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects +[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html \ No newline at end of file diff --git a/src/attributes/diagnostics.md b/src/attributes/diagnostics.md index 1a8bd9f0e..506e2848b 100644 --- a/src/attributes/diagnostics.md +++ b/src/attributes/diagnostics.md @@ -301,154 +301,7 @@ When used on a function in a trait implementation, the attribute does nothing. > let _ = five(); > ``` -## The `debugger_visualizer` attribute - -The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the PDB/ELF generated by `rustc`. -This enables an improved debugger experience for types outside of Rust's standard library. - -### Using `debugger_visualizer` with Natvis - -Natvis is an XML-based framework, and a `.natvis` file declares how a type's fields should be displayed in the debugger view. -A Natvis file is embedded using the `natvis-file` meta item. -Microsoft's [Natvis documentation] can be referenced to help developers write their own `.natvis` files. - -
-Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets. -`-windows-gnu` targets are not currently supported. -
- -Consider a crate with this directory structure: - -```text -/Cargo.toml -/Foo.natvis (Note: the Natvis file does not have to match the name of the crate.) - +-- src - +-- main.rs -``` - -Where `main.rs` contains: - -```rust -#![debugger_visualizer(natvis_file = "../Foo.natvis")] -struct FancyRect { - pub x: f32, - pub y: f32, - pub dx: f32, - pub dy: f32, -} - -fn main() { - let mut fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); -} -``` - -and `Foo.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, 10) + (5, 5) - > LowerLeft: (10, 10) - > UpperLeft: (10, 15) - > UpperRight: (15, 15) - > LowerRight: (15, 10) -``` - -### Using `debugger_visualizer` with GDB - -Developers using GDB are able to embed *pretty printers* onto types. -In GDB, a pretty printer is a structured Python script that describes how a type's fields should be displayed in the debugger view. -These scripts are embedded using the `gdb_script_file` meta item. -GDB's [pretty print documentation] can be referenced by developers to help them write their own `.py` scripts. - -Consider a crate with this directory structure: - -```text -/Cargo.toml -/bar.py (Note: the file does not have to match the name of the crate.) - +-- src - +-- main.rs -``` - -Where `main.rs` contains: - -```rust -#![debugger_visualizer(gdb_script_file = "../bar.py")] -mod person { - pub struct Person { - pub name: String, - pub age: i32, - } -} - -use person::Person; - -fn main() { - let person = Person::new(String::from("Bob"), 10); -} -``` - -and `bar.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 "main::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, `print person` should display: - -``` -"Bob" is 10 years old. -``` - [Clippy]: https://github.com/rust-lang/rust-clippy -[Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects -[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax [_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax From e6f6ce8e17823a04bce7988dc8a60082782312e1 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Tue, 28 Feb 2023 13:01:15 -0800 Subject: [PATCH 03/10] add line --- src/attributes/debugger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index f3dcfcd58..2be68eee9 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -147,4 +147,4 @@ When the crate's debug executable is passed into GDB, `print person` will displa [attributes]: ../attributes.md [Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects -[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html \ No newline at end of file +[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html From 8db722e99b392f946e1228951999a71c5930e9a2 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Wed, 1 Mar 2023 17:04:03 -0800 Subject: [PATCH 04/10] add details for GDB auto-load --- src/attributes/debugger.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index 2be68eee9..d59f28a36 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -38,7 +38,8 @@ struct FancyRect { } fn main() { - let mut fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); + let fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); + Ok(()) } ``` @@ -84,7 +85,12 @@ GDB supports the use of a structured Python script, called a *pretty printer*, t These scripts are embedded using the `gdb_script_file` meta item. For detailed information on pretty printers, refer to GDB's [pretty print documentation]. -Consider a crate with this directory structure: +Embedded pretty printers are not automatically loaded when debugging a binary under GDB. +There are two ways to enable auto-loading embedded pretty printers: +1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "set auto-load safe-path path/to/binary" path/to/binary` (For more information, see GDB's [auto-loading documentation]) +1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. + +Consider a crate called `foobar` with this directory structure: ```text /Cargo.toml @@ -107,7 +113,8 @@ mod person { use person::Person; fn main() { - let person = Person::new(String::from("Bob"), 10); + let bob = Person::new(String::from("Bob"), 10); + Ok(()) } ``` @@ -131,7 +138,7 @@ def lookup(val): lookup_tag = val.type.tag if lookup_tag is None: return None - if "person::Person" == lookup_tag: + if "foobar::person::Person" == lookup_tag: return PersonPrinter(val) return None @@ -139,12 +146,13 @@ def lookup(val): gdb.current_objfile().pretty_printers.append(lookup) ``` -When the crate's debug executable is passed into GDB, `print person` will display: +When the crate's debug executable is passed into GDB, `print bob` will display: ``` "Bob" is 10 years old. ``` +[auto-loading documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html [attributes]: ../attributes.md [Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects [pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html From 2d451878628610d10112477c1ee69967c7a27da2 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Thu, 2 Mar 2023 09:45:36 -0800 Subject: [PATCH 05/10] fix style errors --- src/attributes/debugger.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index d59f28a36..12dcaa1b8 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -1,27 +1,27 @@ # Debugger attributes -The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. +he following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. ## The `debugger_visualizer` attribute -The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the debug information generated by `rustc`. +The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the debug information generated by `rustc`. This enables an improved debugger experience for types outside of Rust's standard library. ### Using `debugger_visualizer` with Natvis Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg that uses declarative rules to customize the display of types. -A Natvis file is embedded using the `natvis-file` meta item. +A Natvis file is embedded using the `natvis-file` meta item. For detailed information on the Natvis format, refer to Microsoft's [Natvis documentation].
-Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets. +Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets.
Consider a crate with this directory structure: ```text /Cargo.toml -/Rectangle.natvis +/Rectangle.natvis +-- src +-- main.rs ``` @@ -81,14 +81,14 @@ When viewed under WinDbg, the `fancy_rect` variable would be shown as follows: ### Using `debugger_visualizer` with GDB -GDB supports the use of a structured Python script, called a *pretty printer*, that describes how a type should be visualized in the debugger view. -These scripts are embedded using the `gdb_script_file` meta item. +GDB supports the use of a structured Python script, called a *pretty printer*, that describes how a type should be visualized in the debugger view. +These scripts are embedded using the `gdb_script_file` meta item. For detailed information on pretty printers, refer to GDB's [pretty print documentation]. Embedded pretty printers are not automatically loaded when debugging a binary under GDB. There are two ways to enable auto-loading embedded pretty printers: 1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "set auto-load safe-path path/to/binary" path/to/binary` (For more information, see GDB's [auto-loading documentation]) -1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. +1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. Consider a crate called `foobar` with this directory structure: @@ -148,7 +148,7 @@ gdb.current_objfile().pretty_printers.append(lookup) When the crate's debug executable is passed into GDB, `print bob` will display: -``` +```text "Bob" is 10 years old. ``` From 5784e5300af75dd65bdb78f9cd949d371421a7a2 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Thu, 2 Mar 2023 10:00:26 -0800 Subject: [PATCH 06/10] fix broken link --- src/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4d9cc1d76..2b17bf45d 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -44,6 +44,7 @@ - [Code generation](attributes/codegen.md) - [Limits](attributes/limits.md) - [Type System](attributes/type_system.md) + - [Debugger](attributes/debugger.md) - [Statements and expressions](statements-and-expressions.md) - [Statements](statements.md) From c3be9034477113b3ba0dd91ebce8867adc75d793 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Thu, 2 Mar 2023 10:28:11 -0800 Subject: [PATCH 07/10] fix rustdoc failures --- src/attributes/debugger.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index 12dcaa1b8..95392f26c 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -28,7 +28,7 @@ Consider a crate with this directory structure: Where `main.rs` contains: -```rust +```rust ignore #![debugger_visualizer(natvis_file = "../Rectangle.natvis")] struct FancyRect { pub x: f32, @@ -39,7 +39,7 @@ struct FancyRect { fn main() { let fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); - Ok(()) + Ok(()); } ``` @@ -101,7 +101,7 @@ Consider a crate called `foobar` with this directory structure: Where `main.rs` contains: -```rust +```rust ignore #![debugger_visualizer(gdb_script_file = "../bar.py")] mod person { pub struct Person { @@ -114,7 +114,7 @@ use person::Person; fn main() { let bob = Person::new(String::from("Bob"), 10); - Ok(()) + Ok(()); } ``` From 1c56d59dddce0588d94812f0bedead4bf1de96b3 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Mon, 6 Mar 2023 11:55:13 -0800 Subject: [PATCH 08/10] address pr comments --- src/attributes/debugger.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index 95392f26c..a41410d3a 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -1,6 +1,6 @@ # Debugger attributes -he following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. +The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. ## The `debugger_visualizer` attribute @@ -9,7 +9,7 @@ This enables an improved debugger experience for types outside of Rust's standar ### Using `debugger_visualizer` with Natvis -Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg that uses declarative rules to customize the display of types. +Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg) that uses declarative rules to customize the display of types. A Natvis file is embedded using the `natvis-file` meta item. For detailed information on the Natvis format, refer to Microsoft's [Natvis documentation]. @@ -90,11 +90,11 @@ There are two ways to enable auto-loading embedded pretty printers: 1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "set auto-load safe-path path/to/binary" path/to/binary` (For more information, see GDB's [auto-loading documentation]) 1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. -Consider a crate called `foobar` with this directory structure: +Consider a crate called `PersonPrinter` with this directory structure: ```text /Cargo.toml -/person_printer.py +/printer.py +-- src +-- main.rs ``` @@ -102,7 +102,7 @@ Consider a crate called `foobar` with this directory structure: Where `main.rs` contains: ```rust ignore -#![debugger_visualizer(gdb_script_file = "../bar.py")] +#![debugger_visualizer(gdb_script_file = "../printer.py")] mod person { pub struct Person { pub name: String, @@ -118,7 +118,7 @@ fn main() { } ``` -and `person_printer.py` contains: +and `printer.py` contains: ```python import gdb @@ -138,7 +138,7 @@ def lookup(val): lookup_tag = val.type.tag if lookup_tag is None: return None - if "foobar::person::Person" == lookup_tag: + if "PersonPrinter::person::Person" == lookup_tag: return PersonPrinter(val) return None From 4dee364a2ccc3162a140dc723950e59ebaccb177 Mon Sep 17 00:00:00 2001 From: Gibby Free Date: Mon, 6 Mar 2023 16:35:32 -0800 Subject: [PATCH 09/10] fix compile errors in code snippets --- src/attributes/debugger.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index a41410d3a..208f6bd82 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -30,16 +30,26 @@ Where `main.rs` contains: ```rust ignore #![debugger_visualizer(natvis_file = "../Rectangle.natvis")] -struct FancyRect { +mod fancy_rect { + pub struct FancyRect { pub x: f32, pub y: f32, pub dx: f32, pub dy: f32, + } + + impl FancyRect { + pub fn new(x: f32, y: f32, dx: f32, dy: f32) -> Self { + FancyRect { x, y, dx, dy } + } + } } +use fancy_rect::FancyRect; + fn main() { let fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); - Ok(()); + () } ``` @@ -108,13 +118,19 @@ mod person { pub name: String, pub age: i32, } + + impl Person { + pub fn new(name: String, age: i32) -> Self { + Person { name, age } + } + } } use person::Person; fn main() { let bob = Person::new(String::from("Bob"), 10); - Ok(()); + () } ``` From 39a0be6dc8210e0f127638ac5cc6820b8ce534df Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 6 May 2023 10:25:55 -0700 Subject: [PATCH 10/10] Updates and copy-edits for debugger_visualizer. --- src/attributes.md | 2 +- src/attributes/debugger.md | 113 +++++++++++++------------------------ 2 files changed, 41 insertions(+), 74 deletions(-) diff --git a/src/attributes.md b/src/attributes.md index 28d49fff1..92ce1cd09 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -272,7 +272,7 @@ The following is an index of all built-in attributes. - [`non_exhaustive`] — Indicate that a type will have more fields/variants added in future. - Debugger - - [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type + - [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type. [Doc comments]: comments.md#doc-comments [ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm diff --git a/src/attributes/debugger.md b/src/attributes/debugger.md index 208f6bd82..6ea80221e 100644 --- a/src/attributes/debugger.md +++ b/src/attributes/debugger.md @@ -1,55 +1,36 @@ # Debugger attributes -The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or LLDB. +The following [attributes] are used for enhancing the debugging experience when using third-party debuggers like GDB or WinDbg. ## The `debugger_visualizer` attribute -The `debugger_visualizer` attribute can be used to embed a debugger visualizer file into the debug information generated by `rustc`. -This enables an improved debugger experience for types outside of Rust's standard library. +The *`debugger_visualizer` attribute* 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. +It uses the [_MetaListNameValueStr_] syntax to specify its inputs, and must be specified as a crate attribute. ### Using `debugger_visualizer` with Natvis Natvis is an XML-based framework for Microsoft debuggers (such as Visual Studio and WinDbg) that uses declarative rules to customize the display of types. -A Natvis file is embedded using the `natvis-file` meta item. For detailed information on the Natvis format, refer to Microsoft's [Natvis documentation]. -
-Currently, this attribute only supports embedding Natvis files on `-windows-msvc` targets. -
+This attribute only supports embedding Natvis files on `-windows-msvc` targets. -Consider a crate with this directory structure: - -```text -/Cargo.toml -/Rectangle.natvis - +-- src - +-- main.rs -``` - -Where `main.rs` contains: +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")] -mod fancy_rect { - pub struct FancyRect { - pub x: f32, - pub y: f32, - pub dx: f32, - pub dy: f32, - } - - impl FancyRect { - pub fn new(x: f32, y: f32, dx: f32, dy: f32) -> Self { - FancyRect { x, y, dx, dy } - } - } -} +#![debugger_visualizer(natvis_file = "Rectangle.natvis")] -use fancy_rect::FancyRect; +struct FancyRect { + x: f32, + y: f32, + dx: f32, + dy: f32, +} fn main() { - let fancy_rect = FancyRect::new(10.0, 10.0, 5.0, 5.0); - () + let fancy_rect = FancyRect { x: 10.0, y: 10.0, dx: 5.0, dy: 5.0 }; + println!("set breakpoint here"); } ``` @@ -58,7 +39,7 @@ and `Rectangle.natvis` contains: ```xml - + ({x},{y}) + ({dx}, {dy}) @@ -82,55 +63,38 @@ When viewed under WinDbg, the `fancy_rect` variable would be shown as follows: ```text > Variables: - > fancy_rect: (10, 10) + (5, 5) - > LowerLeft: (10, 10) - > UpperLeft: (10, 15) - > UpperRight: (15, 15) - > LowerRight: (15, 10) + > 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) ``` ### Using `debugger_visualizer` with GDB GDB supports the use of a structured Python script, called a *pretty printer*, that describes how a type should be visualized in the debugger view. -These scripts are embedded using the `gdb_script_file` meta item. -For detailed information on pretty printers, refer to GDB's [pretty print documentation]. +For detailed information on pretty printers, refer to GDB's [pretty printing documentation]. Embedded pretty printers are not automatically loaded when debugging a binary under GDB. There are two ways to enable auto-loading embedded pretty printers: -1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "set auto-load safe-path path/to/binary" path/to/binary` (For more information, see GDB's [auto-loading documentation]) +1. Launch GDB with extra arguments to explicitly add a directory or binary to the auto-load safe path: `gdb -iex "add-auto-load-safe-path safe-path path/to/binary" path/to/binary` + For more information, see GDB's [auto-loading documentation]. 1. Create a file named `gdbinit` under `$HOME/.config/gdb` (you may need to create the directory if it doesn't already exist). Add the following line to that file: `add-auto-load-safe-path path/to/binary`. -Consider a crate called `PersonPrinter` with this directory structure: - -```text -/Cargo.toml -/printer.py - +-- src - +-- main.rs -``` - -Where `main.rs` contains: +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")] -mod person { - pub struct Person { - pub name: String, - pub age: i32, - } - - impl Person { - pub fn new(name: String, age: i32) -> Self { - Person { name, age } - } - } -} +#![debugger_visualizer(gdb_script_file = "printer.py")] -use person::Person; +struct Person { + name: String, + age: i32, +} fn main() { - let bob = Person::new(String::from("Bob"), 10); - () + let bob = Person { name: String::from("Bob"), age: 10 }; + println!("set breakpoint here"); } ``` @@ -154,7 +118,7 @@ def lookup(val): lookup_tag = val.type.tag if lookup_tag is None: return None - if "PersonPrinter::person::Person" == lookup_tag: + if "foo::Person" == lookup_tag: return PersonPrinter(val) return None @@ -162,13 +126,16 @@ def lookup(val): gdb.current_objfile().pretty_printers.append(lookup) ``` -When the crate's debug executable is passed into GDB, `print bob` will display: +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 [Natvis documentation]: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects -[pretty print documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html +[pretty printing documentation]: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html +[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax