DWARFDUMP(1)

✨ DWARFDUMP ✨

okay bestie, gather round, because we're talking about the dwarfdump manual page (that's the DWARFDUMP() one, section 1, in case you were wondering which flavor of manual we're in). This is the tool that reaches into an ELF object and pulls out all its DWARF debug info. It's giving ✨archaeologist but for compiler secrets✨ and honestly? obsessed. πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

dwarfdump [options] objectfilename

πŸ’– DESCRIPTION πŸ’–

The dwarfdump command prints or checks DWARF sections, and it does exactly what you ask it to via specific options. With no options (but with the required objectfilename β€” it's not optional, bestie) all sections print. BUT. Some sections literally cannot be printed independently in a safe way, so those only get printed at the offsets where the .debug_info section actually refers to them. No cap. 🫢

For split-dwarf (DWARF5) object files, go peek at the Split Object Files discussion, DWARF5 section 7.3.

Nearly all options come in the traditional (single-letter) form and in a long-options form with meaningful names. Brand-new options? Long-options form only, sorry. ✨

With no options, dwarfdump prints a basic set of DWARF section information. The second you give it any option on the command line, that basic set is ignored and you have to tell dwarfdump what to print or check yourself (for example by adding the -a option). It's very "you wanted this, now you're driving" energy. πŸš—

The printing options and the checking options are mutually exclusive β€” if checking options are selected, the section details are not printed. When errors are encountered, dwarfdump does attempt to print sufficient context so you can understand exactly where the error is in the DWARF. This change makes checking really large object files much easier. iconic behavior, honestly. πŸ‘‘

The format is intended to be human readable. If a script is going to parse the output, the --format-dense (-d) option is useful. πŸ€–

DWARF expressions are broken out so that each expression (like DW_OP_plus, for example) prints in a block on a separate line. Want the previous behavior back? Sort of like --format-dense but only applying to blocks of DWARF expression operators (DW_OP*)? Then --format-expr-ops-joined is useful. And if you drop that option into the dwarfdump.conf file (see the file itself for the format), it will apply without you needing to put it on the command line. lowkey magical. 🌟

Not all sections actually exist in any given object file. obviously. πŸ™ˆ

⚠️ The output format may change from release to release, so it is unwise to depend too heavily on the format. bestie, do not hardcode your parser to it, I'm begging.

Frame information (.debug_frame and .eh_frame) is heavily dependent on the ABI/ISA of the object file. By default we use a generic set of register names handling up to 100 registers named r0-r99.

There are three different ways compiler writers separate the DWARF information from an executable/shared-object:

  • One is DWARF5 Split Dwarf (the --file-tied option is useful for these).
  • Another is GNU debuglink β€” libdwarf automatically finds the DWARF when given the name of the executable; use --no-follow-debuglink to suppress this and make it possible to print the backtrace data in section .eh_frame.
  • The third way is on Macos: the debug DWARF is in a separate object (dwarfdump/libdwarf automatically find it if it is present, and --no-follow-debuglink suppresses this finding).

See also --suppress-debuglink-crc. 🌸

In many cases one can get additional detail by specifying -v (sometimes -v -v gets even more, see the --verbose discussion below). When printing DIEs (Debugging Information Entries) the options -G (showing global offsets) and -M (naming the DW_FORM* of attributes) β€” or their -- counterparts β€” can be a great aid to understanding DWARF. fr fr, they're little cheatsheets built right in. 🧚

The --format-registers (-R) option uses a built-in generic register name set handling up to 1200 registers named r0-r1199.

The --file-abi=<abi> (-x abi=<abi>) description below shows how to name an abi and use that to guide the --print-frame (-f) or --print-eh-frame (-F) processing.

One of --print-frame (-f) or --print-eh-frame (-F) implies lots of abi (register names, register counts) in the output, but sections other than frame sections may also need register names.

πŸ’€ Unless the cpu for the object file being dumped has many registers, do not use --format-registers or -file-abi=<abi>, as those can be needlessly slow when dumping frame sections. Instead, use the correct abi (if it exists in dwarfdump.conf) or a generic such as --file-abi=abi=generic100 or --file-abi=abi=generic500.

The most useful abi choices are likely mips or x86 or x86_64 or ppc or arm. Without --format-registers (-R) or -file-abi=<abi> (-x abi=<abi>), dwarfdump uses a compiled-in generic set of register names.

If no --file-name=<path> (-x name=<path>) is given, dwarfdump looks for:

  • "./dwarfdump.conf"
  • "$HOME/dwarfdump.conf"
  • "$HOME/.dwarfdump.conf"
  • "<install-prefix>/lib/dwarfdump.conf"

…and takes the first one it finds. Use the --show-dwarfdump-conf option to see what dwarfdump finds. And if one or more --file-name=<path> (-x name=<path>) is given, the last of these is used and all other such files are ignored. last one wins, periodt. πŸ’…


πŸ” ERROR CHECKING πŸ”

Some checking (-k) options (see "Check DWARF Integrity" in the help output) print so-called harmless errors. These are compiler errors that do not cause any known problem and are only detected inside libdwarf itself. These are difficult to properly report in dwarfdump, and any error strings may not appear close to the time the error was encountered. so like… don't panic if the timing looks weird. 😭

If one or more abbreviation attributes are duplicated in an abbreviation list for some Debugging Information Entry (a direct violation of the DWARF standard), you will find that adding the option --no-dup-attr-check to the options will enable you to see the broken set of attributes by changing a flag inside libdwarf itself. One could use the option -kD to find out what duplicated attributes exist in the object file. detective mode activated πŸ”Ž

If zlib compression was used on the DWARF sections in the object file being read, the real section names such as .zdebug_info etc will be reported by dwarfdump. When dwarfdump says something is at offset 55 of .zdebug_info (or the like), keep in mind that the offset applies to the uncompressed section (in memory), not the .zdebug_ compressed section in objectfilename. important!! 🫢


🌈 URI-STYLE INPUT STRINGS 🌈

The <objectfilename> and all the options taking name strings look for URIs and translate the URI strings to characters by default. So any single % character is treated as if the following two characters are hex digits representing the underlying true character.

Various characters are meaningful to shells (such as bash or sh) and to getopt (such as the space character). If the URI translation does anything, it prints the before and after of the URI translation on standard output, so inspection of the first lines of output will show if URI did anything. The actual options themselves are assumed to be non-URI. So in the option --format-producer=S&T (-cS&T) the & character might cause input issues, so --format-producer=S%26T should be used instead. To actually input a single % character (in a name, for example), double it to %% on the command line (or use %25).

Options --format-suppress-uri (-U) (turning off URI interpretation) and --format-suppress-uri-msg (-q) (making finding URI sequences silent) give finer control of URI interpretation. πŸŽ€

As an example, to get a string 'a b' make the string 'a%20b' (here the quote (') is for exposition, not part of the string, though quote is certainly problematic in a name). Instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b'. Any characters can be typed in URI style, not just characters which are problematic to the shell or getopt.

🌟 We strongly suggest you not type URI-style characters where such are not needed, or use the % character itself in command line strings, unless you must.

πŸŽ€ URI-STYLE OUTPUT (printing) πŸŽ€

Dwarfdump translates any characters in strings which are not ordinary printable ASCII (and some which are ASCII) in the reverse of the previous section. It prints into a uri-style output in the form %xx, where xx are hex digits in the form of ASCII 0-9a-0f. The percent character (%) is printed as '%25'

This is a clumsy way to deal with UTF-8 strings and a sensible way to deal with the low ASCII values that on many systems cause one's terminal to behave oddly. Such translations are not idempotent, so dwarfdump avoids doing the translation more than once on any string. See option --format-suppress-sanitize below to eliminate the output transformation. ✨


✨ PRINTING OPTIONS ✨

okay so these are the "what do you want dumped to your screen" buttons πŸ’… every single one of them, no skips, we're doing this properly.

  • --print-all (-a) β€” prints every section as independently as it possibly can. Sections that are safe to print on their own (like .debug_abbrev) get their relevant info printed right there in the report β€” sometimes that depends on -v btw, so don't come for me if it looks different.
  • --print-abbrev (-b) β€” prints the .debug_abbrev section. heads up bestie: the DWARF specs do not rule out garbage data areas in .debug_abbrev (like, if nothing references them from .debug_info), so any garbage bytes can make this print fail. not us, the spec, iykyk 🫠
  • --print-loc (-c) β€” prints locations lists.
  • --print-debug-gnu β€” prints the .debug_gnu_pubnames and .debug_gnu_typenames sections.
  • --print-fission β€” prints the .gdb_index, .debug_cu_index, .debug_tu_index, .gnu.debuglink, and .note.gnu.build-id sections.
  • --print-gnu-debuglink β€” prints .gnu_debuglink and .note.gnu.build-id sections.
  • --print-frame (-f) β€” prints the .debug_frame section.
  • --print-eh-frame (-F) β€” prints the GNU .eh_frame section.
  • --print-info (-i) β€” prints the .debug_info section.
  • --print-fission (-I) β€” prints any .gdb_index, .debug_cu_index, and .debug_tu_index sections that actually exist in the object. (yes, --print-fission shows up twice in this list. no, you're not hallucinating. it's giving iconic chaos πŸŽ€)
  • --print-gnu-debuglink β€” if the .gnu_debuglink section is there, its content gets printed. if the .note.gnu.build-id section is there, its content gets printed. and if a DWARF-containing file named by the content of .gnu_debuglink exists, the name gets printed too. (also listed twice. we love consistency πŸ™ˆ)
  • --print-lines (-l) β€” prints the .debug_info section and the line section data that goes with it.
  • --print-lines-short (-ls) β€” same as above, .debug_info plus its line section data, but it omits the <pc> address. literally made for when you need to compare line sections from objects with tiny little differences. obsessed.
  • --print-macinfo (-m) β€” prints the .debug_macinfo (DWARF 2, 3, 4) and .debug_macro (DWARF5) sections. the .debug_macro reporting may show output labeled MACRONOTES, which calls out macro content that might be questionable πŸ‘€ see also --check-macros (-kw).
  • --print-ranges (-N) β€” prints the .debug_ranges section. same warning as abbrev: the DWARF specs don't rule out garbage data areas in .debug_ranges (if they're not referenced from .debug_info), so garbage bytes can make this print fail. πŸ’€
  • --print-pubnames (-p) β€” prints the .debug_pubnames section.
  • --print-str-offsets β€” prints the .debug_str_offsets section.
  • --print-aranges (-r) β€” prints the .debug_aranges section.
  • --print-strings (-s) β€” prints .debug_string section.
  • --print-section-allocations β€” prints a lil short summary of section memory allocations, and it summarizes malloc and mmap section allocations separately. cute and organized 🌸
  • --print-static (-ta) β€” prints the IRIX-only sections .debug_static_funcs and .debug_static_vars. retro queen πŸ‘‘
  • --print-type (-y) β€” prints the .debug_pubtypes section (plus .debug_typenames, an SGI IRIX-only section).
  • --version (-V) β€” prints a dwarfdump date/version string and then stops. bye bestie πŸ¦‹

πŸ” CHECKING OPTIONS πŸ”

this is the "find everything wrong with it" section and honestly? it's a lot. grab a snack. πŸ“

  • --check-all (-ka) β€” turns on all the checking options except --check-frame-extended (-kxe), because that one might be slow enough that you don't wanna run it every single time.
  • --check-abbrev (-kb) β€” checks for certain abbreviations section errors while reading DIEs.
  • --check-macros (-kw) β€” checks for issues in DWARF5 .debug_macro, and flags stuff that might be questionable (not necessarily an error) with the string MACRONOTES β€” and yeah, it reports some MACRONOTES that --print-macinfo won't show. it also checks .debug_macinfo, but less thoroughly, and it never emits MACRONOTES for .debug_macinfo. see also --print-macinfo (-m). (regrettably inconsistent spelling… πŸ’€)
  • --check-constants (-kc) β€” checks for errors in constants in debug_info.
  • -check-show (-kd) β€” turns on full reporting of error totals per producer. (the default shows less detail.) note the single dash, that's literally how it's written, don't fix it bestie πŸ’…
  • --check-silent-ks β€” turns off some verbose checking detection.
  • --check-attr-dup (-kD) β€” turns on reporting of duplicated attributes. duplicated attributes on a single DW_TAG are improper DWARF, but at least one compiler emitted them, so here we are πŸ™ƒ
  • --check-pubnames (-ke) β€” turns on reading pubnames and checking for fde errors.
  • --check-frame-info (-kf) β€” turns on checking for FDE errors (.debug_frame and .eh_frame).
  • --check-files-lines (-kF) β€” turns on checking for line table errors.
  • --check-gaps (-kg) β€” turns on checking for unused gaps in .debug_info. these gaps aren't an error, just a waste of space. wasteful behavior honestly 😭
  • --check-unique (-kG) β€” prints only unique errors. error lines get simplified (hex numbers removed, for example), and when a given message string would otherwise show up again, it gets suppressed. so much cleaner ✨
  • --check-summary (-ki) β€” makes a summary of checking results per compiler (producer) get printed at the end.
  • --check-loc (-kl) β€” turns on locations list checking.
  • --check-ranges (-km) β€” turns on checking of ranges.
  • --check-aranges (-kM) β€” turns on checking of aranges.
  • --check-tag-attr (-kr) β€” turns on DIE tag-attr combinations checking, hunting for surprising attributes on DIE tags. it prints a DWARF-CHECK message for each one it finds. it does not report common extensions as errors. a summary of usage gets printed at the end. common extensions to the standard are allowed as if they were standard. see the -C (--format-extensions) option to show common extensions as DWARF-CHECK messages, and see -kuf (--check-usage-extended) to add extra details to that summary report.
  • --check-usage (-ku) β€” same as -kr, except only the summary prints at the end β€” the detailed per-instance DWARF-CHECK messages don't print. lowkey the chill version 😌
  • --check-attr-encodings (-kE) β€” checks the integer encoding representation of constant FORMs in debug_info, working out whether those integer values could fit in fewer bytes if represented in LEB128, and reports the space saving that would achieve. math girlies rise 🧚
  • --check-forward-refs (-kR) β€” turns on reading DIEs and checking for forward declarations from DW_AT_specification attributes. (not an error, but it can be a source of inefficiency for debuggers.)
  • --check-self-refs (-kS) β€” turns on checking DIE references for circular references. πŸŒ€
  • --check-tag-tag (-kt) β€” turns on tag-tag combinations checking, looking for surprising parent-child DIE relationships. it does not report common extensions as errors. common extensions to the standard are allowed as if they were standard. see the -C (--format-extensions) option to show common extensions as errors.
  • --check-frame-basic (-kx) β€” turns on basic frames checking for .debug_frame and .eh_frame.
  • --check-frame-extended (-kxe) β€” turns off basic check_frames and turns on extended frame checking for .debug_frame and .eh_frame. this option can be slow. like, plan your afternoon slow.
  • --check-type (-ky) β€” turns on type_offset checking (making sure local attribute offsets refer to what they're supposed to) and checks that DW_AT_decl_file and some other offsets refer to appropriate locations.

🌈 MISCELLANEOUS OPTIONS 🌈

the grab-bag. the leftovers drawer. the main character energy corner. πŸ‘‘

  • --allocate-via-mmap β€” when possible, libdwarf will use mmap rather than malloc to load section content into memory.
  • --suppress-de-alloc-tree β€” tells libdwarf to skip tracking and dealloc of all memory allocations, and just rely on your code to do the dealloc. use valgrind or a compiler option like -fsanitize to check your application for failures to dealloc appropriately. it improves libdwarf performance a few percent. few percent for a little chaos, we love a trade-off πŸ’…
  • --suppress-debuglink-crc β€” tells libdwarf to avoid calculating debuglink crc values, which saves some runtime at startup and removes a useful check. however, finding alternate debuglink or buildid files stays enabled. so like, you lose a check but keep the search 🌸
  • --no-follow-debuglink β€” tells dwarfdump and libdwarf to pay absolutely zero attention to .gnu.debuglink or .gnu.note.buildid or Macos dSYM references. not me, not today πŸ™…β€β™€οΈ

✨ OPTION MODIFIERS ✨

okay so these are the little sidekicks πŸ’… they don't do the main-character thing all on their own β€” they tag along with OTHER options and change how those behave. supporting cast, but iconic for it.

  • --format-extensions (-C) β€” this is a secondary option that comes after --check-tag-tag (-kt) or --check-tag-attr (-kr) or (yeah the source page literally just trails off on an "or" there, we're respecting it πŸ’€). normally, when you're checking for tag-tag or tag-attribute combinations, both the standard combinations AND some common extensions are allowed (meaning they don't get reported). flip this on and the extensions get taken out of the class of allowed combinations. no more free passes, bestie.
  • -kuf (--check-usage-extended) β€” this one modifies --check-tag-attr (-kr) or --check-usage (-ku) so it prints extra deets in the summary. drop the -kuf (--check-usage-extended) before or after the option it modifies, either way works. 🫢
  • --format-dense (-d) β€” when printing DIEs, this puts all the attributes for each DIE on the same (long) line as the TAG. why do you care? because searching for DIE information (like with grep) gets so much simpler when the entire DIE lives on one line. life-changing, fr.
  • --format-suppress-offsets (-D) β€” turns off the display of section offsets and attribute values in printed output. so the .debug_info output is just TAGs and Attributes, that's it. for pubnames (and the like) it removes offsets from the output. for locations lists it removes offsets from the output too β€” but that's useless, since the attribute values don't show so neither does the location data. πŸ™ˆ
  • --format-ellipsis (-e) β€” turns on truncation of attribute and tag names. like, DW_TAG_foo becomes just foo. not compatible with checking, only useful for printing DIEs.
  • --format-global-offsets (-G) β€” when printing, add global offsets to the offsets printed. simple as that. ✨
  • --format-limit=<num> (-H number) β€” when printing or checking .debug_info, this terminates the search after number compilation units. when printing frame information it terminates the FDE reporting after number FDEs, and the CIE reporting (which happens if you add -v) after number CIEs. example: --format-limit=1
  • --format-attr-name (-M) β€” when printing, show the FORM for each attribute. add a -v (or more than one) and you also get details of any form indirection. πŸ‘‘
  • --format-suppress-lookup (-n) β€” when printing frames, this turns off the search for function names in inner scopes. unless the language used to build the object file supports function definitions in inner scopes, there is no point looking for function names in inner scopes. and on a really large object, the search can take more time than you want to wait. this option suppresses the inner scope search. bye πŸ‘‹
  • --file-output=<path> (-Ofile=<path>) β€” the path gets used as the file name for output instead of writing to stdout (stdout is the default).
  • --format-suppress-data (-Q) β€” suppresses section data printing (this gets set automatically with a checking option).
  • --format-suppress-sanitize β€” suppresses the default string-printing translations, so non-ascii and non-printable characters from the object file are printed as-is. see "URI-STYLE OUTPUT" above.
  • --format-suppress-uri (-U) β€” suppresses the default URI translation of the following options on the command line. see "URI-STYLE INPUT STRINGS" above.
  • --format-registers (-R) β€” when printing frames for ABIs with lots of registers, this lets up to 1200 registers be named (like R999) without choosing an ABI with, for example, -x abi=ppc or, equivalently, --file-abi=ppc.
  • --verbose (-v) β€” increases the detail shown when printing. in some sections, using more -v options will increase the detail (one to four are useful) or may change the report to show, for example, the actual line-data-commands instead of the resultant line-table. two to four -v options make a difference when printing DIEs and rnglists (-i), lines (-l), frames (-f,-F), gdb_index(-I). additional -v beyond four do not currently add-to or change the output. four is the ceiling, periodt.
  • --show-dwarfdump-conf β€” shows what files are checked to find a dwarfdump.conf and its register naming tables. πŸ”

πŸ” LIMITING OUTPUT πŸ”

the simplest limiting option is to stop the examination/printing after <num> compilation units. see -H and --format-limit above. this option also limits the number of FDEs and CIEs printed from any .debug_frame or .eh_frame section.

the --search (-S) options print information about the compilation unit and DIE where the string(s) appear. these cannot be combined with other options. at most one of each of the following is effective (so for example you can only have one 'match', but you can have a 'match', an 'any', and a 'regex'). any --search (-S) causes the .debug_info section to be inspected. no checking options or printing options should be supplied with --search(-S) options. the strings should use URI-style to avoid any conflicts with the command-line parser applicable (bash, sh, ...) or getopt(), as well as using URI to deal with searching for strings in non-ASCII such as French, (etc) or the now-nearly-universal UTF8. the regex implementation only allows ASCII in the expression, and the expression only handles basic regular expressions, which are like Posix Basic Regular Expressions (PBRE), but the () grouping construct in PBRE seems unnecessary here so we suggest not using () grouping.

these are particularly useful when the amount of DWARF information output by -i is multiple gigabytes of data. 😭

if -Sv is used instead of -S, the number of occurrences is printed. (see below for an example).

  • --search-match=<string> (-Smatch=string)
  • --search-match-count=<string> (-Svmatch=string) β€” when printing DIEs, for each tag value or attribute name that matches string exactly, print the compilation unit information and its section offset. any CU with no match is not printed. the string is read as a URI string. the count (Sv) form reports the count of occurrences.
  • --search-any=<string> (-Sany=string)
  • --search-any-count=<string> (-Svany=string) β€” when printing DIEs, for each tag value or attribute name that contains string somewhere in the tag or attribute (case insensitive), print the compilation unit information and its section offset. any CU with no match is not printed. the string is read as a URI string. the count (Sv) form reports the count of occurrences.
  • --search-regex=string (-Sregex=string)
  • --search-regex-count=string (-Svregex=string) β€” when printing DIEs, for each tag value or attribute name where the string regular expression matches, print the compilation unit information and its section offset. any CU with no match is not printed. the string is read as a URI string. the count (Sv) form reports the count of occurrences.

the string cannot have spaces or other characters which are meaningful to getopt(3), and the shell will strip off quotes and other characters. so the string is assumed to be in URI style and is translated. in other words, to match 'a b' make the -S string 'a%20b'. instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b' (the ' are for exposition here, not part of the strings). any characters can be typed in URI style, not just characters which are problematic to the shell or getopt.

the --search-any (-Sany) and --regex-any (-Sregex) options are only usable if regular-expression library functions required are found at configure time.

the --search-print (-W) option is a modifier to the -S option, and increases the amount of output -S prints. an example v modifier to the -S option is shown below. and we show the -W in context with a -S option. πŸ’–

  • --search-match-count=string β€” prints information about the DIEs that -S matches and prints the count of occurrences.
-S match=string1 -W
  • --search-match=string1 --search-print-tree β€” prints the parent tree and the children tree for the DIEs that --search-match matches.
-S match=string2 -Wp
  • --search-match=string2 --search-print-parent β€” prints the parent tree for the DIEs that -S matches.
-S match=string3 -Wc
  • --search-match=string3 --search-print-children β€” prints the children tree for the DIEs that -S matches.
  • --format-gcc (-cg) β€” restricts printing/checking to compilers whose producer string starts with 'GNU' and turns off -cs.
  • --format-snc (-cs) β€” restricts printing/checking to compilers whose producer string starts with 'SN' and turns off -cg.
  • --format-producer=<name> (-c<name>) β€” restricts printing/checking to compilers whose producer string contains 'name' (not case sensitive). the 'name' is read as a URI string. πŸ¦‹

✨ OTHER OPTIONS (the rest of the goodies) ✨

  • -x name=<path>
  • --file-name=/p/a/t/h.conf (also written -xname=/p/a/t/h.conf) β€” bestie, the path you hand over here is treated as the name of a file that's assumed to be a dwarfdump.conf-style file. And yeah, that path gets read as a URI string. πŸ¦‹
  • -x abi=ppc
  • --file-abi=ppc β€” picks the abi (pulled out of a dwarfdump.conf file) that gets used when printing frame info β€” ppc is just the example here, don't come for me. The abi is read as a URI string. πŸ’…
  • --format-group-number=<n> (-x groupnumber=<n>) β€” okay so picture an object file that has both DWARF5 split dwarf (like .debug_info.dwo) and ordinary DWARF sections (like .debug_info) all chillin' in that one single object file. In that situation you must use --format-group-number=2 to print the dwo sections. And if you also toss in --file-tied=<path> naming the object file, it ties in the non-dwo skeleton sections β€” heads up, that <path> points at the skeleton object file when the main object file is dwo/dwp. πŸ‘‘
  • -x tied=/t/i/depath
  • --file-tied=/t/i/depath β€” this one's for when you're opening a main object that happens to be a .dwo or .dwp file. Say /path/to/myapp.dwp is the split-dwarf object and /path/to/myapp is the executable β€” then you go:
dwarfdump --file-tied=/path/to/myapp /path/to/myapp.dwp

The tied file path names the executable, which is the one holding the .debug_addr section that the main object might be referring to. Peep Split Objects (aka Debug Fission) in the DWARF5 standard for the lore. But fr fr β€” this cannot be used with Macos debug or GNU debuglink, because those kinds of files just don't have a Split Dwarf object file. Sorry bestie. 😭

  • -x line5=s2l
  • --file-line5=s2l β€” normally you'd only touch this to test libdwarf interfaces. There are 4 different interface function sets, and this option lets you choose which one gets used so we can confirm they all actually work. The choices are:
    • s2l β€” the default; allows standard and two-level line tables using the latest interface functions
    • std β€” allows standard single level line tables using the latest interface functions
    • orig β€” allows DWARF2,3,4 original line tables using an older interface function set
    • orig2l β€” allows original line tables and some two-level line tables using an older interface set
  • --print-producers
  • -P β€” when you're checking stuff, this adds the list of compilation-unit names seen for each producer-compiler to the printed checking results. 🌸
  • -q
  • --format-suppress-uri-msg β€” when a URI gets found and translated while the command line is being read, this keeps things quiet about the translation. Like, it won't print the original and translated option strings. 🀫
  • -u cuname
  • --format-file=<file> β€” turns on selective printing of DIEs (printing just like -i). Only the DIEs for a compilation unit that match the name you gave get printed. So if the compilation unit is ./a/b/c.c, the cuname you provide should be c.c β€” everything up through that final path-separating / gets ignored. And if cuname starts with a /, then the entire name string of a compilation unit has to match cuname. The file is read as a URI string. πŸ’–
  • -U
  • --format-suppress-uri β€” turns off URI interpretation of the command line strings entirely. Heads up: it has to be on the command line before any URI strings are encountered to be fully effective. Honestly? Likely something no one needs to do. πŸ’€
  • -h
  • --help β€” shows this man page. Iconic, honestly. ✨

🧚 SPLIT DWARF 🧚

With Split Dwarf (DWARF5), the main body of the DWARF lives in a separate file β€” usually with a name suffix of .dwp or .dwo. It's giving long-distance relationship, lowkey. πŸ¦‹

So for example, if /path/to/myapp.dwp is the split-dwarf object and /path/to/myapp is the executable, you do:

dwarfdump --file-tied=/path/to/myapp /path/to/myapp.dwp

The tied file path names the executable, which is the one that has the .debug_addr section and other sections that might be referred to from the .dwo/.dwp object.

See Split Object Files (sometimes called Debug Fission) in the DWARF5 standard, section 7.3. Go read it, bestie, it's lore. πŸ“š


🌈 FILES 🌈

  • dwarfdump
  • ./dwarfdump.conf
  • $(HOME)/.dwarfdump.conf
  • $(HOME)/dwarfdump.conf
  • <install-prefix>/lib/dwarfdump.conf

πŸ“ NOTES πŸ“

As of version 2.2.0, dwarfdump will check block FORMS like DW_FORM_block2 (etc) for content that looks like a valid UTF8 string. Anything like that gets printed in hex with a leading 0x and ending with a colon (:). Right after that, the string β€” but only if it's longer than 1 byte and less than 5000 bytes long β€” gets printed with a leading Block As Quoted String , and that leading bit is there specifically so searching for such things in dwarfdump output stays relatively simple. πŸ’…

In some cases compilers use DW_FORM_data1 (for example), and in those cases the signedness of the value has to be taken from context. Rather than trying to figure out the context, dwarfdump prints the value with both signednesses whenever there's ambiguity about the correct interpretation. Like:

DW_AT_const_value           176(as signed = -80)

For normal DWARF consumers that correctly and fully evaluate all attributes, there's no ambiguity of signedness at all β€” the ambiguity exists for dwarfdump because dwarfdump evaluates DIEs in a simple order and doesn't keep track of much context. Not me being honest about my own limitations, but okay. πŸ™ˆ


πŸ› BUGS πŸ›

Support for printing certain DWARF5 location expressions is incomplete. Report problems to libdwarf-list -at- linuxmail -dot- org. 🫢


okay and that's the whole page, bestie β€” this was the DWARFDUMP(1) man page, footer and all, and yeah the footer just says DWARFDUMP() with no version or date baked in, so consider this your lil sign-off. slay, go read some DWARF, you've got this. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from