diff options
Diffstat (limited to 'vendor/smallvec/debug_metadata')
-rw-r--r-- | vendor/smallvec/debug_metadata/README.md | 111 | ||||
-rw-r--r-- | vendor/smallvec/debug_metadata/smallvec.natvis | 35 |
2 files changed, 146 insertions, 0 deletions
diff --git a/vendor/smallvec/debug_metadata/README.md b/vendor/smallvec/debug_metadata/README.md new file mode 100644 index 0000000..9a5596b --- /dev/null +++ b/vendor/smallvec/debug_metadata/README.md @@ -0,0 +1,111 @@ +## Debugger Visualizers + +Many languages and debuggers enable developers to control how a type is +displayed in a debugger. These are called "debugger visualizations" or "debugger +views". + +The Windows debuggers (WinDbg\CDB) support defining custom debugger visualizations using +the `Natvis` framework. To use Natvis, developers write XML documents using the natvis +schema that describe how debugger types should be displayed with the `.natvis` extension. +(See: https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) +The Natvis files provide patterns which match type names a description of how to display +those types. + +The Natvis schema can be found either online (See: https://code.visualstudio.com/docs/cpp/natvis#_schema) +or locally at `<VS Installation Folder>\Xml\Schemas\1033\natvis.xsd`. + +The GNU debugger (GDB) supports defining custom debugger views using Pretty Printers. +Pretty printers are written as python scripts that describe how a type should be displayed +when loaded up in GDB/LLDB. (See: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html#Pretty-Printing) +The pretty printers provide patterns, which match type names, and for matching +types, describe 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). + +### Embedding Visualizers + +Through the use of the currently unstable `#[debugger_visualizer]` attribute, the `smallvec` +crate can embed debugger visualizers into the crate metadata. + +Currently the two types of visualizers supported are Natvis and Pretty printers. + +For Natvis files, when linking an executable with a crate that includes Natvis files, +the MSVC linker will embed the contents of all Natvis files into the generated `PDB`. + +For pretty printers, the compiler will encode the contents of the pretty printer +in the `.debug_gdb_scripts` section of the `ELF` generated. + +### Testing Visualizers + +The `smallvec` crate supports testing debugger visualizers defined for this crate. The entry point for +these tests are `tests/debugger_visualizer.rs`. These tests are defined using the `debugger_test` and +`debugger_test_parser` crates. The `debugger_test` crate is a proc macro crate which defines a +single proc macro attribute, `#[debugger_test]`. For more detailed information about this crate, +see https://crates.io/crates/debugger_test. The CI pipeline for the `smallvec` crate has been updated +to run the debugger visualizer tests to ensure debugger visualizers do not become broken/stale. + +The `#[debugger_test]` proc macro attribute may only be used on test functions and will run the +function under the debugger specified by the `debugger` meta item. + +This proc macro attribute has 3 required values: + +1. The first required meta item, `debugger`, takes a string value which specifies the debugger to launch. +2. The second required meta item, `commands`, takes a string of new line (`\n`) separated list of debugger +commands to run. +3. The third required meta item, `expected_statements`, takes a string of new line (`\n`) separated list of +statements that must exist in the debugger output. Pattern matching through regular expressions is also +supported by using the `pattern:` prefix for each expected statement. + +#### Example: + +```rust +#[debugger_test( + debugger = "cdb", + commands = "command1\ncommand2\ncommand3", + expected_statements = "statement1\nstatement2\nstatement3")] +fn test() { + +} +``` + +Using a multiline string is also supported, with a single debugger command/expected statement per line: + +```rust +#[debugger_test( + debugger = "cdb", + commands = " +command1 +command2 +command3", + expected_statements = " +statement1 +pattern:statement[0-9]+ +statement3")] +fn test() { + +} +``` + +In the example above, the second expected statement uses pattern matching through a regular expression +by using the `pattern:` prefix. + +#### Testing Locally + +Currently, only Natvis visualizations have been defined for the `smallvec` crate via `debug_metadata/smallvec.natvis`, +which means the `tests/debugger_visualizer.rs` tests need to be run on Windows using the `*-pc-windows-msvc` targets. +To run these tests locally, first ensure the debugging tools for Windows are installed or install them following +the steps listed here, [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). +Once the debugging tools have been installed, the tests can be run in the same manner as they are in the CI +pipeline. + +#### Note + +When running the debugger visualizer tests, `tests/debugger_visualizer.rs`, they need to be run consecutively +and not in parallel. This can be achieved by passing the flag `--test-threads=1` to rustc. This is due to +how the debugger tests are run. Each test marked with the `#[debugger_test]` attribute launches a debugger +and attaches it to the current test process. If tests are running in parallel, the test will try to attach +a debugger to the current process which may already have a debugger attached causing the test to fail. + +For example: + +``` +cargo test --test debugger_visualizer --features debugger_visualizer -- --test-threads=1 +``` diff --git a/vendor/smallvec/debug_metadata/smallvec.natvis b/vendor/smallvec/debug_metadata/smallvec.natvis new file mode 100644 index 0000000..8731860 --- /dev/null +++ b/vendor/smallvec/debug_metadata/smallvec.natvis @@ -0,0 +1,35 @@ +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> + <Type Name="smallvec::SmallVec<array$<*,*>>" Priority="Medium"> + <Intrinsic Name="is_inline" Expression="$T2 >= capacity" /> + <Intrinsic Name="len" Expression="is_inline() ? capacity : data.variant1.value.len" /> + <Intrinsic Name="data_ptr" Expression="is_inline() ? data.variant0.value.__0.value.value : data.variant1.value.ptr.pointer" /> + + <DisplayString>{{ len={len()} is_inline={is_inline()} }}</DisplayString> + <Expand> + <Item Name="[capacity]">is_inline() ? $T2 : capacity</Item> + <Item Name="[len]">len()</Item> + <Item Name="[data_ptr]">data_ptr()</Item> + + <ArrayItems> + <Size>len()</Size> + <ValuePointer>data_ptr()</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <Type Name="smallvec::SmallVec<array$<*,*>>" Priority="MediumLow"> + <Intrinsic Name="is_inline" Expression="$T2 >= capacity" /> + <Intrinsic Name="len" Expression="is_inline() ? capacity : data.heap.__1" /> + <Intrinsic Name="data_ptr" Expression="is_inline() ? data.inline.value.value.value : data.heap.__0.pointer" /> + <DisplayString>{{ len={len()} is_inline={is_inline()} }}</DisplayString> + <Expand> + <Item Name="[capacity]">is_inline() ? $T2 : capacity</Item> + <Item Name="[len]">len()</Item> + + <ArrayItems> + <Size>len()</Size> + <ValuePointer>data_ptr()</ValuePointer> + </ArrayItems> + </Expand> + </Type> +</AutoVisualizer>
\ No newline at end of file |