|
1 | | -## Debugger Visualizers |
2 | | - |
3 | | -Many languages and debuggers enable developers to control how a type is |
4 | | -displayed in a debugger. These are called "debugger visualizations" or "debugger |
5 | | -views". |
6 | | - |
7 | | -The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using |
8 | | -the `Natvis` framework. To use Natvis, developers write XML documents using the natvis |
9 | | -schema that describe how debugger types should be displayed with the `.natvis` extension. |
10 | | -(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) |
11 | | -The Natvis files provide patterns which match type names a description of how to display |
12 | | -those types. |
13 | | - |
14 | | -The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) |
15 | | -or locally at `<VS Installation Folder>\Xml\Schemas\1033\natvis.xsd`. |
16 | | - |
17 | | -The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. |
18 | | -Pretty printers are written as python scripts that describe how a type should be displayed |
19 | | -when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) |
20 | | -The pretty printers provide patterns, which match type names, and for matching |
21 | | -types, descibe how to display those types. (For writing a pretty printer, see: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter). |
22 | | - |
23 | | -### Embedding Visualizers |
24 | | - |
25 | | -Through the use of the `#[debugger_visualizer]` attribute, the `url` crate can embed |
26 | | -debugger visualizers into the crate metadata. |
27 | | - |
28 | | -Currently the two types of visualizers supported are Natvis and Pretty printers. |
29 | | - |
30 | | -For Natvis files, when linking an executable with a crate that includes Natvis files, |
31 | | -the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. |
32 | | - |
33 | | -For pretty printers, the compiler will encode the contents of the pretty printer |
34 | | -in the `.debug_gdb_scripts` section of the `ELF` generated. |
35 | | - |
36 | | -### Testing Visualizers |
37 | | - |
38 | | -The `url` crate supports testing debugger visualizers defined for this crate. The entry point for |
39 | | -these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and |
40 | | -`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a |
41 | | -single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, |
42 | | -see https://crates.io/crates/debugger_test. The CI pipeline for the `url` crate has been updated |
43 | | -to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. |
44 | | - |
45 | | -The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the |
46 | | -function under the debugger specified by the `debugger` meta item. |
47 | | - |
48 | | -This proc macro attribute has 3 required values: |
49 | | - |
50 | | -1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. |
51 | | -2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger |
52 | | -commands to run. |
53 | | -3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of |
54 | | -statements that must exist in the debugger output. Pattern matching through regular expressions is also |
55 | | -supported by using the `pattern:` prefix for each expected statement. |
56 | | - |
57 | | -#### Example: |
58 | | - |
59 | | -```rust |
60 | | -#[debugger_test( |
61 | | - debugger = "cdb", |
62 | | - commands = "command1\ncommand2\ncommand3", |
63 | | - expected_statements = "statement1\nstatement2\nstatement3")] |
64 | | -fn test() { |
65 | | - |
66 | | -} |
67 | | -``` |
68 | | - |
69 | | -Using a multiline string is also supported, with a single debugger command/expected statement per line: |
70 | | - |
71 | | -```rust |
72 | | -#[debugger_test( |
73 | | - debugger = "cdb", |
74 | | - commands = " |
75 | | -command1 |
76 | | -command2 |
77 | | -command3", |
78 | | - expected_statements = " |
79 | | -statement1 |
80 | | -pattern:statement[0-9]+ |
81 | | -statement3")] |
82 | | -fn test() { |
83 | | - |
84 | | -} |
85 | | -``` |
86 | | - |
87 | | -In the example above, the second expected statement uses pattern matching through a regular expression |
88 | | -by using the `pattern:` prefix. |
89 | | - |
90 | | -#### Testing Locally |
91 | | - |
92 | | -Currently, only Natvis visualizations have been defined for the `url` crate via `debug_metadata/url.natvis`, |
93 | | -which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. |
94 | | -To run these tests locally, first ensure the debugging tools for Windows are installed or install them following |
95 | | -the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). |
96 | | -Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI |
97 | | -pipeline. |
98 | | - |
99 | | -#### Note |
100 | | - |
101 | | -When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively |
102 | | -and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to |
103 | | -how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger |
104 | | -and attaches it to the current test process. If tests are running in parallel, the test will try to attach |
105 | | -a debugger to the current process which may already have a debugger attached causing the test to fail. |
106 | | - |
107 | | -For example: |
108 | | - |
109 | | -``` |
110 | | -cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 |
111 | | -``` |
| 1 | +## Debugger Visualizers |
| 2 | + |
| 3 | +Many languages and debuggers enable developers to control how a type is |
| 4 | +displayed in a debugger. These are called "debugger visualizations" or "debugger |
| 5 | +views". |
| 6 | + |
| 7 | +The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using |
| 8 | +the `Natvis` framework. To use Natvis, developers write XML documents using the natvis |
| 9 | +schema that describe how debugger types should be displayed with the `.natvis` extension. |
| 10 | +(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) |
| 11 | +The Natvis files provide patterns which match type names a description of how to display |
| 12 | +those types. |
| 13 | + |
| 14 | +The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) |
| 15 | +or locally at `<VS Installation Folder>\Xml\Schemas\1033\natvis.xsd`. |
| 16 | + |
| 17 | +The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. |
| 18 | +Pretty printers are written as python scripts that describe how a type should be displayed |
| 19 | +when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) |
| 20 | +The pretty printers provide patterns, which match type names, and for matching |
| 21 | +types, descibe how to display those types. (For writing a pretty printer, see: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter). |
| 22 | + |
| 23 | +### Embedding Visualizers |
| 24 | + |
| 25 | +Through the use of the `#[debugger_visualizer]` attribute, the `url` crate can embed |
| 26 | +debugger visualizers into the crate metadata. |
| 27 | + |
| 28 | +Currently the two types of visualizers supported are Natvis and Pretty printers. |
| 29 | + |
| 30 | +For Natvis files, when linking an executable with a crate that includes Natvis files, |
| 31 | +the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. |
| 32 | + |
| 33 | +For pretty printers, the compiler will encode the contents of the pretty printer |
| 34 | +in the `.debug_gdb_scripts` section of the `ELF` generated. |
| 35 | + |
| 36 | +### Testing Visualizers |
| 37 | + |
| 38 | +The `url` crate supports testing debugger visualizers defined for this crate. The entry point for |
| 39 | +these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and |
| 40 | +`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a |
| 41 | +single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, |
| 42 | +see https://crates.io/crates/debugger_test. The CI pipeline for the `url` crate has been updated |
| 43 | +to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. |
| 44 | + |
| 45 | +The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the |
| 46 | +function under the debugger specified by the `debugger` meta item. |
| 47 | + |
| 48 | +This proc macro attribute has 3 required values: |
| 49 | + |
| 50 | +1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. |
| 51 | +2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger |
| 52 | +commands to run. |
| 53 | +3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of |
| 54 | +statements that must exist in the debugger output. Pattern matching through regular expressions is also |
| 55 | +supported by using the `pattern:` prefix for each expected statement. |
| 56 | + |
| 57 | +#### Example: |
| 58 | + |
| 59 | +```rust |
| 60 | +#[debugger_test( |
| 61 | + debugger = "cdb", |
| 62 | + commands = "command1\ncommand2\ncommand3", |
| 63 | + expected_statements = "statement1\nstatement2\nstatement3")] |
| 64 | +fn test() { |
| 65 | + |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +Using a multiline string is also supported, with a single debugger command/expected statement per line: |
| 70 | + |
| 71 | +```rust |
| 72 | +#[debugger_test( |
| 73 | + debugger = "cdb", |
| 74 | + commands = " |
| 75 | +command1 |
| 76 | +command2 |
| 77 | +command3", |
| 78 | + expected_statements = " |
| 79 | +statement1 |
| 80 | +pattern:statement[0-9]+ |
| 81 | +statement3")] |
| 82 | +fn test() { |
| 83 | + |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +In the example above, the second expected statement uses pattern matching through a regular expression |
| 88 | +by using the `pattern:` prefix. |
| 89 | + |
| 90 | +#### Testing Locally |
| 91 | + |
| 92 | +Currently, only Natvis visualizations have been defined for the `url` crate via `debug_metadata/url.natvis`, |
| 93 | +which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. |
| 94 | +To run these tests locally, first ensure the debugging tools for Windows are installed or install them following |
| 95 | +the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). |
| 96 | +Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI |
| 97 | +pipeline. |
| 98 | + |
| 99 | +#### Note |
| 100 | + |
| 101 | +When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively |
| 102 | +and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to |
| 103 | +how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger |
| 104 | +and attaches it to the current test process. If tests are running in parallel, the test will try to attach |
| 105 | +a debugger to the current process which may already have a debugger attached causing the test to fail. |
| 106 | + |
| 107 | +For example: |
| 108 | + |
| 109 | +``` |
| 110 | +cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 |
| 111 | +``` |
0 commit comments