Skip to content

Commit

Permalink
Merge pull request #274 from k3DW/gdb
Browse files Browse the repository at this point in the history
Write GDB pretty-printers for all containers and iterators
  • Loading branch information
k3DW committed Aug 23, 2024
2 parents a39cf60 + 111a503 commit 1ebe692
Show file tree
Hide file tree
Showing 7 changed files with 934 additions and 65 deletions.
1 change: 1 addition & 0 deletions doc/unordered/changes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
`boost::concurrent_flat_set` operations to allow for safe mutable modification of elements
({github-pr-url}/265[PR#265^]).
* In Visual Studio Natvis, supported any container with an allocator that uses fancy pointers. This applies to any fancy pointer type, as long as the proper Natvis customization point "Intrinsic" functions are written for the fancy pointer type.
* Added GDB pretty-printers for all containers and iterators. For a container with an allocator that uses fancy pointers, these only work if the proper pretty-printer is written for the fancy pointer type itself.

== Release 1.86.0

Expand Down
64 changes: 64 additions & 0 deletions doc/unordered/debuggability.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,67 @@ Iterators are displayed similarly to their standard counterparts. An iterator is
=== Fancy pointers

The container visualizations also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has natvis customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost_unordered.natvis].

== GDB Pretty-Printers

All containers and iterators have a custom GDB pretty-printer.

=== Using in your project

Always, when using pretty-printers, you must enable pretty-printing like below. This is typically a one-time setup.

```plaintext
(gdb) set print pretty on
```

By default, if you compile into an ELF binary format, your binary will contain the Boost.Unordered pretty-printers. To use the embedded pretty-printers, ensure you allow auto-loading like below. This must be done every time you load GDB, or add it to a ".gdbinit" file.

```plaintext
(gdb) add-auto-load-safe-path [/path/to/executable]
```

You can choose to compile your binary _without_ embedding the pretty-printers by defining `BOOST_ALL_NO_EMBEDDED_GDB_PRINTERS`, which disables the embedded GDB pretty-printers for all Boost libraries that have this feature.

You can load the pretty-printers externally from the non-embedded Python script. Add the script, link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py], using the `source` command as shown below.

```plaintext
(gdb) source [/path/to/boost]/libs/unordered/extra/boost_unordered_printers.py
```

=== Visualization structure

The visualizations mirror the standard unordered containers. The map containers display an association from key to mapped value. The set containers display an association from index to value. An iterator is either displayed with its item, or as an end iterator. Here is what may be shown for an example `boost::unordered_map`, an example `boost::unordered_set`, and their respective begin and end iterators.

```plaintext
(gdb) print example_unordered_map
$1 = boost::unordered_map with 3 elements = {["C"] = "c", ["B"] = "b", ["A"] = "a"}
(gdb) print example_unordered_map_begin
$2 = iterator = { {first = "C", second = "c"} }
(gdb) print example_unordered_map_end
$3 = iterator = { end iterator }
(gdb) print example_unordered_set
$4 = boost::unordered_set with 3 elements = {[0] = "c", [1] = "b", [2] = "a"}
(gdb) print example_unordered_set_begin
$5 = iterator = { "c" }
(gdb) print example_unordered_set_end
$6 = iterator = { end iterator }
```

The other containers are identical other than replacing "`boost::unordered_{map|set}`" with the appropriate template name when displaying the container itself. Note that each sub-element (i.e. the key, the mapped value, or the value) is displayed based on its own printing settings which may include its own pretty-printer.

Both the SIMD and the non-SIMD implementations are viewable through the GDB pretty-printers.

For open-addressing containers where xref:#hash_quality_container_statistics[container statistics] are enabled, you can obtain these statistics by calling `get_stats()` on the container, from within GDB. This is overridden in GDB as an link:https://sourceware.org/gdb/current/onlinedocs/gdb.html/Xmethod-API.html[xmethod], so it will not invoke any C++ synchronization code. See the following printout as an example for the expected format.

```plaintext
(gdb) print example_flat_map.get_stats()
$1 = [stats] = {[insertion] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}},
[successful_lookup] = {[count] = 0, [probe_length] = {avg = 0.0, var = 0.0, dev = 0.0},
[num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}, [unsuccessful_lookup] = {[count] = 5,
[probe_length] = {avg = 1.0, var = 0.0, dev = 0.0},
[num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}}
```

=== Fancy pointers

The pretty-printers also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has GDB pretty-printer customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py].
Loading

0 comments on commit 1ebe692

Please sign in to comment.