It's quite hard work sometimes - there's a lot in there - but the capabilities available are amazing and it's well worth nosing around.
I also recommend just hitting TAB a lot and seeing what commands are suggested. Then use the "help"command to find out more.
My employer also hosts some articles that digest some knowledge we've gained into a more palatable form: https://undo.io/resources/gdb-watchpoint/
But debuggers like GDB have built in infrastructure for expressing how to display structured, potentially nested data structures - it's built for the purpose and powerful, so it's nice to bring it to bear if you've not already got something equivalent in they program.
The other important thing is that the debugger's pretty printers work on a core file, without needing a live process.
This would make bugs around state in Debug impls much more complicated, for example. This can creep in under a few layers of indirection - ultimately calling a function that gets the value of an interned string would be one example.
It’s gotten much better. Primitive structures which are defined by their fields and builtins like `Vec`, `HashMap`, `String`, are handled good. But structures in library or user code which use “raw” and other non-trivial representations, but provide an opaque safe API, I can only introspect the non-trivial fields.
This annotation is exactly what those custom structures need.
What platform / debugger are you on? I'd expect the GDB pretty-printers (which from the article it looks like Rust has been shipping by default for the standard library) to be taking care of this relatively well - e.g. looking at https://github.com/rust-lang/rust/pull/72357 it appears that `HashMap` and `HashSet` have printers.
(Raw C++ data structures without some form of pretty printing are also incomprehensible for normal development - and I'd be surprised if third party libraries were particularly good at shipping pretty printers, though I may be wrong!)