Hopefully, you’ll have arrived at this section because you want to extend Stackdb’s platform support. If you hoped to get advice on how to improve its design, unfortunately this won’t be much help to you.
Here’s a quick overview of the source tree:
Probably what you’re curious about is, why are there three different data structures describing symbols? struct symbol
and struct lsymbol
in dwdebug/, and struct bsymbol
in target/. First, we desired to provide first-class support for looking up symbol expressions, not just individual symbols. It’s much easier for the user to look up an expression like “init_task.mm.mm_count”, instead of the individual members and/or typed pointers that make up the chain – and given this chain (an lsymbol), the user can ask the to lookup a bsymbol (a “bound” symbol – bound to a target region, because the debugfile in which the symbol was found is associated with a specific memory region) – and then to load it. In other words, the target library can load symbol expressions, not just individual symbols. This is quite convenient.
Unfortunately, it complicates the API. The target API (bsymbols) essentially wraps the dwdebug API (symbols and lsymbols) functions.
Finally, symbols are reference counted. This is necessary because of optimizations in the dwdebug/ library that strive to remove duplicate debuginfo data (there can be a lot of it!). Users are never exposed to symbols that might be deleted; the reference counting is primarily used to guard symbols while the loading algorithms are running and conducting space-saving optimizations.
This means when users lookup a symbol, they must release it via bsymbol_release(), lsymbol_release(), or symbol_release(). Unfortunate, but that’s how it has to be to enable the optimizations.