2284 lines · plain
1llvm-debuginfo-analyzer - Print a logical representation of low-level debug information.2========================================================================================3 4.. program:: llvm-debuginfo-analyzer5 6.. contents::7 :local:8 9SYNOPSIS10--------11:program:`llvm-debuginfo-analyzer` [*options*] [*filename ...*]12 13DESCRIPTION14-----------15:program:`llvm-debuginfo-analyzer` parses debug and text sections in16binary object files and prints their contents in a logical view, which17is a human-readable representation that closely matches the structure18of the original user source code. Supported object file formats include19ELF, Mach-O, WebAssembly, PDB and COFF.20 21The **logical view** abstracts the complexity associated with the22different low-level representations of the debugging information that23is embedded in the object file. :program:`llvm-debuginfo-analyzer`24produces a canonical view of the debug information regardless of how it25is formatted. The same logical view will be seen regardless of object26file format, assuming the debug information correctly represents the27same original source code.28 29The logical view includes the following **logical elements**: *type*,30*scope*, *symbol* and *line*, which are the basic software elements used31in the C/C++ programming language. Each logical element has a set of32**attributes**, such as *types*, *classes*, *functions*, *variables*,33*parameters*, etc. The :option:`--attribute` can be used to specify which34attributes to include when printing a logical element. A logical element35may have a **kind** that describes specific types of elements. For36instance, a *scope* could have a kind value of *function*, *class*,37*namespace*.38 39:program:`llvm-debuginfo-analyzer` defaults to print a pre-defined40layout of logical elements and attributes. The command line options can41be used to control the printed elements (:option:`--print`), using a42specific layout (:option:`--report`), matching a given pattern43(:option:`--select`, :option:`--select-offsets`). Also, the output can44be limited to specified logical elements using (:option:`--select-lines`,45:option:`--select-scopes`, :option:`--select-symbols`,46:option:`--select-types`).47 48:program:`llvm-debuginfo-analyzer` can also compare a set of logical49views (:option:`--compare`), to find differences and identify possible50debug information syntax issues (:option:`--warning`) in any object file.51 52OPTIONS53-------54:program:`llvm-debuginfo-analyzer` options are separated into several55categories, each tailored to a different purpose:56 57 * :ref:`general_` - Standard LLVM options to display help, version, etc.58 * :ref:`attributes_` - Describe how to include different details when59 printing an element.60 * :ref:`print_` - Specify which elements will be included when printing61 the view.62 * :ref:`output_` - Describe the supported formats when printing the view.63 * :ref:`report_` - Describe the format layouts for view printing.64 * :ref:`select_` - Allows to use specific criteria or conditions to65 select which elements to print.66 * :ref:`compare_` - Compare logical views and print missing and/or67 added elements.68 * :ref:`warning_` - Print the warnings detected during the creation69 of the view.70 * :ref:`internal_` - Internal analysis of the logical view.71 72.. _general_:73 74GENERAL75~~~~~~~76This section describes the standard help options, used to display the77usage, version, response files, etc.78 79.. option:: -h, --help80 81 Show help and usage for this command. (--help-hidden for more).82 83.. option:: --help-list84 85 Show help and usage for this command without grouping the options86 into categories (--help-list-hidden for more).87 88.. option:: --help-hidden89 90 Display all available options.91 92.. option:: --print-all-options93 94 Print all option values after command line parsing.95 96.. option:: --print-options97 98 Print non-default options after command line parsing99 100.. option:: --version101 102 Display the version of the tool.103 104.. option:: @<FILE>105 106 Read command-line options from `<FILE>`.107 108If no input file is specified, :program:`llvm-debuginfo-analyzer`109defaults to read `a.out` and return an error when no input file is found.110 111If `-` is used as the input file, :program:`llvm-debuginfo-analyzer`112reads the input from its standard input stream.113 114.. _attributes_:115 116ATTRIBUTES117~~~~~~~~~~118The following options enable attributes given for the printed elements.119The attributes are divided in categories based on the type of data being120added, such as: internal offsets in the binary file, location descriptors,121register names, user source filenames, additional element transformations,122toolchain name, binary file format, etc.123 124.. option:: --attribute=<value[,value,...]>125 126 With **value** being one of the options in the following lists.127 128 .. code-block:: text129 130 =all: Include all the below attributes.131 =extended: Add low-level attributes.132 =standard: Add standard high-level attributes.133 134 The following attributes describe the most common information for a135 logical element. They help to identify the lexical scope level; the136 element visibility across modules (global, local); the toolchain name137 and source language that produced the binary file.138 139 .. code-block:: text140 141 =global: Element referenced across Compile Units.142 =format: Object file format name.143 =language: Source language name.144 =level: Lexical scope level (File=0, Compile Unit=1).145 =local: Element referenced only in the Compile Unit.146 =producer: Toolchain identification name.147 148 The following attributes describe files and directory names from the149 user source code, where the elements are declared or defined; functions150 with public visibility across modules. These options allow to map the151 elements to their user code location, for cross references purposes.152 153 .. code-block:: text154 155 =directories: Directories referenced in the debug information.156 =filename: Filename where the element is defined.157 =files: Files referenced in the debug information.158 =pathname: Pathname where the object is defined.159 =publics: Function names that are public.160 161 The following attributes describe additional logical element source162 transformations, in order to display built-in types (int, bool, etc.);163 parameters and arguments used during template instantiation; parent164 name hierarchy; array dimensions information; compiler generated165 elements; type sizes and the underlying types associated with the types166 aliases.167 168 .. code-block:: text169 170 =argument: Template parameters replaced by its arguments.171 =base: Base types (int, bool, etc.).172 =generated: Compiler generated elements.173 =encoded: Template arguments encoded in the template name.174 =qualified: The element type include parents in its name.175 =reference: Element declaration and definition references.176 =size: Sizes for compound and base types.177 =subrange: Subrange encoding information for arrays.178 =typename: Template parameters.179 =underlying: Underlying type for type definitions.180 181 The following attributes describe the debug location information for182 a symbol or scope. It includes the symbol percentage coverage and any183 gaps within the location layout; ranges determining the code sections184 attached to a function. When descriptors are used, the target processor185 registers are displayed.186 187 .. code-block:: text188 189 =coverage: Symbol location coverage.190 =gaps: Missing debug location (gaps).191 =location: Symbol debug location.192 =range: Debug location ranges.193 =register: Processor register names.194 195 The following attributes are associated with low level details, such196 as: offsets in the binary file; discriminators added to the lines of197 inlined functions in order to distinguish specific instances; debug198 lines state machine registers; elements discarded by the compiler199 (inlining) or by the linker optimizations (dead-stripping); system200 compile units generated by the MS toolchain in PDBs.201 202 .. code-block:: text203 204 =discarded: Discarded elements by the linker.205 =discriminator: Discriminators for inlined function instances.206 =inserted: Generated inlined abstract references.207 =linkage: Object file linkage name.208 =offset: Debug information offset.209 =qualifier: Line qualifiers (Newstatement, BasicBlock, etc).210 =zero: Zero line numbers.211 212 The following attribute described specific information for the **PE/COFF**213 file format. It includes MS runtime types.214 215 .. code-block:: text216 217 =system: Display PDB's MS system elements.218 219 The above attributes are grouped into *standard* and *extended*220 categories that can be enabled.221 222 The *standard* group, contains those attributes that add sufficient223 information to describe a logical element and that can cover the224 normal situations while dealing with debug information.225 226 .. code-block:: text227 228 =base229 =coverage230 =directories231 =discriminator232 =filename233 =files234 =format235 =language236 =level237 =producer238 =publics239 =range240 =reference241 =zero242 243 The *extended* group, contains those attributes that require a more244 extended knowledge about debug information. They are intended when a245 lower level of detail is required.246 247 .. code-block:: text248 249 =argument250 =discarded251 =encoded252 =gaps253 =generated254 =global255 =inserted256 =linkage257 =local258 =location259 =offset260 =operation261 =pathname262 =qualified263 =qualifier264 =register265 =size266 =subrange267 =system268 =typename269 270.. _print_:271 272PRINT273~~~~~274The following options describe the elements to print. The layout used275is determined by the :option:`--report`. In the tree layout, all the276elements have their enclosing lexical scopes printed, even when not277explicitly specified.278 279.. option:: --print=<value[,value,...]>280 281 With **value** being one of the options in the following lists.282 283 .. code-block:: text284 285 =all: Include all the below attributes.286 287 The following options print the requested elements; in the case of any288 given select conditions (:option:`--select`), only those elements that289 match them, will be printed. The **elements** value is a convenient290 way to specify instructions, lines, scopes, symbols and types all at291 once.292 293 .. code-block:: text294 295 =elements: Instructions, lines, scopes, symbols and types.296 =instructions: Assembler instructions for code sections.297 =lines: Source lines referenced in the debug information.298 =scopes: Lexical blocks (function, class, namespace, etc).299 =symbols: Symbols (variable, member, parameter, etc).300 =types: Types (pointer, reference, type alias, etc).301 302 The following options print information, collected during the creation303 of the elements, such as: scope contributions to the debug information;304 summary of elements created, printed or matched (:option:`--select`);305 warnings produced during the view creation.306 307 .. code-block:: text308 309 =sizes: Debug Information scopes contributions.310 =summary: Summary of elements allocated, selected or printed.311 =warnings: Warnings detected.312 313 Note: The **--print=sizes** option is ELF specific.314 315.. _output_:316 317OUTPUT318~~~~~~319The following options describe how to control the output generated when320printing the logical elements.321 322.. option:: --output-file=<path>323 324 Redirect the output to a file specified by <path>, where - is the325 standard output stream.326 327:program:`llvm-debuginfo-analyzer` has the concept of **split view**.328When redirecting the output from a complex binary format, it is329**divided** into individual files, each one containing the logical view330output for a single compilation unit.331 332.. option:: --output-folder=<name>333 334 The folder to write a file per compilation unit when **--output=split**335 is specified.336 337.. option:: --output-level=<level>338 339 Only print elements up to the given **lexical level** value. The input340 file is at lexical level zero and a compilation unit is at lexical level341 one.342 343.. option:: --output=<value[,value,...]>344 345 With **value** being one of the options in the following lists.346 347 .. code-block:: text348 349 =all: Include all the below outputs.350 351 .. code-block:: text352 353 =json: Use JSON as the output format (Not implemented).354 =split: Split the output by Compile Units.355 =text: Use a free form text output.356 357.. option:: --output-sort=<key>358 359 Primary key when ordering the elements in the output (default: line).360 Sorting by logical element kind, requires be familiarity with the361 element kind selection options (:option:`--select-lines`,362 :option:`--select-scopes`, :option:`--select-symbols`,363 :option:`--select-types`), as those options describe the different364 logical element kinds.365 366 .. code-block:: text367 368 =none: Unsorted output (i.e. as read from input).369 =id: Sort by unique element ID.370 =kind: Sort by element kind.371 =line: Sort by element line number.372 =name: Sort by element name.373 =offset: Sort by element offset.374 375.. _report_:376 377REPORT378~~~~~~379Depending on the task being executed (print, compare, select), several380layouts are supported to display the elements in a more suitable way,381to make the output easier to understand.382 383.. option:: --report=<value[,value,...]>384 385 With **value** being one of the options in the following list.386 387 .. code-block:: text388 389 =all: Include all the below reports.390 391 .. code-block:: text392 393 =children: Elements and children are displayed in a tree format.394 =list: Elements are displayed in a tabular format.395 =parents: Elements and parents are displayed in a tree format.396 =view: Elements, parents and children are displayed in a tree format.397 398The **list** layout presents the logical elements in a tabular form399without any parent-child relationship. This may be the preferred way to400display elements that match specific conditions when comparing logical401views, making it easier to find differences.402 403The **children**, **parents** and **view** layout displays the elements404in a tree format, with the scopes representing their nodes, and types,405symbols, lines and other scopes representing the children. The layout406shows the lexical scoping relationship between elements, with the binary407file being the tree root (level 0) and each compilation unit being a408child (level 1).409 410The **children** layout includes the elements that match any given411criteria (:option:`--select`) or (:option:`--compare`) and its children.412 413The **parents** layout includes the elements that match any given414criteria (:option:`--select`) or (:option:`--compare`) and its parents.415 416The combined **view** layout includes the elements that match any given417criteria (:option:`--select`) or (:option:`--compare`), its parents418and children.419 420**Notes**:421 4221. When a selection criteria (:option:`--select`) is specified with no423 report option, the **list** layout is selected.4242. The comparison mode always uses the **view** layout.425 426.. _select_:427 428SELECTION429~~~~~~~~~430When printing an element, different data can be included and it varies431(:option:`--attribute`) from data directly associated with the binary432file (offset) to high level details such as coverage, lexical scope433level, location. As the printed output can reach a considerable size,434several selection options, enable printing of specific elements.435 436The pattern matching can ignore the case (:option:`--select-nocase`)437and be extended to use regular expressions (:option:`--select-regex`).438 439ELEMENTS440^^^^^^^^441The following options allow printing of elements that match the given442<pattern>, offset <value> or an element <condition>.443 444.. option:: --select=<pattern>445 446 Print all elements whose name or line number matches the given <pattern>.447 448.. option:: --select-offsets=<value[,value,...]>449 450 Print all elements whose offset matches the given values. See451 :option:`--attribute` option.452 453.. option:: --select-elements=<condition[,condition,...]>454 455 Print all elements that satisfy the given <condition>. With **condition**456 being one of the options in the following list.457 458 .. code-block:: text459 460 =discarded: Discarded elements by the linker.461 =global: Element referenced across Compile Units.462 =optimized: Optimized inlined abstract references.463 464.. option:: --select-nocase465 466 Pattern matching is case-insensitive when using :option:`--select`.467 468.. option:: --select-regex469 470 Treat any <pattern> strings as regular expressions when selecting with471 :option:`--select` option. If :option:`--select-nocase` is specified,472 the regular expression becomes case-insensitive.473 474If the <pattern> criteria is too general, a more selective option can475be specified to target a particular category of elements:476lines (:option:`--select-lines`), scopes (:option:`--select-scopes`),477symbols (:option:`--select-symbols`) and types (:option:`--select-types`).478 479These options require knowledge of the debug information format (DWARF,480CodeView), as the given **kind** describes a very specific type481of element.482 483LINES484^^^^^485The following options allow printing of lines that match the given <kind>.486The given criteria describes the debug line state machine registers.487 488.. option:: --select-lines=<kind[,kind,...]>489 490 With **kind** being one of the options in the following list.491 492 .. code-block:: text493 494 =AlwaysStepInto: marks an always step into.495 =BasicBlock: Marks a new basic block.496 =Discriminator: Line that has a discriminator.497 =EndSequence: Marks the end in the sequence of lines.498 =EpilogueBegin: Marks the start of a function epilogue.499 =LineAssembler: Lines that correspond to disassembly text.500 =LineDebug: Lines that correspond to debug lines.501 =NeverStepInto: marks a never step into.502 =NewStatement: Marks a new statement.503 =PrologueEnd: Marks the end of a function prologue.504 505SCOPES506^^^^^^507The following options allow printing of scopes that match the given <kind>.508 509.. option:: --select-scopes=<kind[,kind,...]>510 511 With **kind** being one of the options in the following list.512 513 .. code-block:: text514 515 =Aggregate: A class, structure or union.516 =Array: An array.517 =Block: A generic block (lexical block or exception block).518 =CallSite: A call site.519 =CatchBlock: An exception block.520 =Class: A class.521 =CompileUnit: A compile unit.522 =EntryPoint: A subroutine entry point.523 =Enumeration: An enumeration.524 =Function: A function.525 =FunctionType: A function pointer.526 =InlinedFunction: An inlined function.527 =Label: A label.528 =LexicalBlock: A lexical block.529 =Module: A module.530 =Namespace: A namespace.531 =Root: The element representing the main scope.532 =Structure: A structure.533 =Subprogram: A subprogram.534 =Template: A template definition.535 =TemplateAlias: A template alias.536 =TemplatePack: A template pack.537 =TryBlock: An exception try block.538 =Union: A union.539 540SYMBOLS541^^^^^^^542The following options allow printing of symbols that match the given <kind>.543 544.. option:: --select-symbols=<kind[,kind,...]>545 546 With **kind** being one of the options in the following list.547 548 .. code-block:: text549 550 =CallSiteParameter: A call site parameter.551 =Constant: A constant symbol.552 =Inheritance: A base class.553 =Member: A member class.554 =Parameter: A parameter to function.555 =Unspecified: Unspecified parameters to function.556 =Variable: A variable.557 558TYPES559^^^^^560The following options allow printing of types that match the given <kind>.561 562.. option:: --select-types=<kind[,kind,...]>563 564 With **kind** being one of the options in the following list.565 566 .. code-block:: text567 568 =Base: Base type (integer, boolean, etc).569 =Const: Constant specifier.570 =Enumerator: Enumerator.571 =Import: Import declaration.572 =ImportDeclaration: Import declaration.573 =ImportModule: Import module.574 =Pointer: Pointer type.575 =PointerMember: Pointer to member function.576 =Reference: Reference type.577 =Restrict: Restrict specifier.578 =RvalueReference: R-value reference.579 =Subrange: Array subrange.580 =TemplateParam: Template parameter.581 =TemplateTemplateParam: Template template parameter.582 =TemplateTypeParam: Template type parameter.583 =TemplateValueParam: Template value parameter.584 =Typedef: Type definition.585 =Unspecified: Unspecified type.586 =Volatile: Volatile specifier.587 588.. _compare_:589 590COMPARE591~~~~~~~592When dealing with debug information, there are situations when the593printing of the elements is not the correct approach. That is the case,594when we are interested in the effects caused by different versions of595the same toolchain, or the impact of specific compiler optimizations.596 597For those cases, we are looking to see which elements have been added598or removed. Due to the complicated debug information format, it is very599difficult to use a regular diff tool to find those elements; even600impossible when dealing with different debug formats.601 602:program:`llvm-debuginfo-analyzer` supports a logical element comparison,603allowing to find semantic differences between logical views, produced by604different toolchain versions or even debug information formats.605 606When comparing logical views created from different debug formats, its607accuracy depends on how close the debug information represents the608user code. For instance, a logical view created from a binary file with609DWARF debug information may include more detailed data than a logical610view created from a binary file with CodeView debug information.611 612The following options describe the elements to compare.613 614.. option:: --compare=<value[,value,...]>615 616 With **value** being one of the options in the following list.617 618 .. code-block:: text619 620 =all: Include all the below elements.621 622 .. code-block:: text623 624 =lines: Include lines.625 =scopes: Include scopes.626 =symbols: Include symbols.627 =types: Include types.628 629:program:`llvm-debuginfo-analyzer` takes the first binary file on the630command line as the **reference** and the second one as the **target**.631To get a more descriptive report, the comparison is done twice. The632reference and target views are swapped, in order to produce those633**missing** elements from the target view and those **added** elements634to the reference view.635 636See :option:`--report` options on how to describe the comparison637reports.638 639.. _warning_:640 641WARNING642~~~~~~~643When reading the input object files, :program:`llvm-debuginfo-analyzer`644can detect issues in the raw debug information. These may not be645considered fatal to the purpose of printing a logical view but they can646give an indication about the quality and potentially expose issues with647the generated debug information.648 649The following options describe the warnings to be recorded for later650printing, if they are requested by :option:`--print`.651 652.. option:: --warning=<value[,value,...]>653 654 With **value** being one of the options in the following list.655 656 .. code-block:: text657 658 =all: Include all the below warnings.659 660 The following options collect additional information during the creation661 of the logical view, to include invalid coverage values and locations662 for symbols; invalid code ranges; lines that are zero.663 664 .. code-block:: text665 666 =coverages: Invalid symbol coverages values.667 =lines: Debug lines that are zero.668 =locations: Invalid symbol locations.669 =ranges: Invalid code ranges.670 671.. _internal_:672 673INTERNAL674~~~~~~~~675 For a better understanding of the logical view, access to more detailed676 internal information could be needed. Such data would help to identify677 debug information processed or incorrect logical element management.678 Typically these kind of options are available only in *debug* builds.679 680 :program:`llvm-debuginfo-analyzer` supports these advanced options in681 both *release* and *debug* builds.682 683.. option:: --internal=<value[,value,...]>684 685 With **value** being one of the options in the following list.686 687 .. code-block:: text688 689 =all: Include all the below options.690 691 The following options allow to check the integrity of the logical view;692 collect the debug tags that are processed or not implemented; ignore the693 logical element line number, to facilitate the logical view comparison694 when using external comparison tools; print the command line options695 used to invoke :program:`llvm-debuginfo-analyzer`.696 697 .. code-block:: text698 699 =id: Print unique element ID.700 =cmdline: Print command line.701 =integrity: Check elements integrity.702 =none: Ignore element line number.703 =tag: Debug information tags.704 705 **Note:** For ELF format, the collected tags represent the debug tags706 that are not processed. For PE/COFF format, they represent the tags707 that are processed.708 709EXAMPLES710--------711This section includes some real binary files to show how to use712:program:`llvm-debuginfo-analyzer` to print a logical view and to713diagnose possible debug information issues.714 715TEST CASE 1 - GENERAL OPTIONS716~~~~~~~~~~~~~~~~~~~~~~~~~~~~~717The below example is used to show different output generated by718:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86719ELF target with Clang (-O0 -g):720 721.. code-block:: c++722 723 1 using INTPTR = const int *;724 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {725 3 if (ParamBool) {726 4 typedef int INTEGER;727 5 const INTEGER CONSTANT = 7;728 6 return CONSTANT;729 7 }730 8 return ParamUnsigned;731 9 }732 733PRINTING MODE734^^^^^^^^^^^^^735In this mode :program:`llvm-debuginfo-analyzer` prints the *logical view*736or portions of it, based on criteria patterns (including regular737expressions) to select the kind of *logical elements* to be included in738the output.739 740BASIC DETAILS741"""""""""""""742The following command prints basic details for all the logical elements743sorted by the debug information internal offset; it includes its lexical744level and debug info format.745 746.. code-block:: none747 748 llvm-debuginfo-analyzer --attribute=level,format749 --output-sort=offset750 --print=scopes,symbols,types,lines,instructions751 test-dwarf-clang.o752 753or754 755.. code-block:: none756 757 llvm-debuginfo-analyzer --attribute=level,format758 --output-sort=offset759 --print=elements760 test-dwarf-clang.o761 762Each row represents an element that is present within the debug763information. The first column represents the scope level, followed by764the associated line number (if any), and finally the description of765the element.766 767.. code-block:: none768 769 Logical View:770 [000] {File} 'test-dwarf-clang.o' -> elf64-x86-64771 772 [001] {CompileUnit} 'test.cpp'773 [002] 2 {Function} extern not_inlined 'foo' -> 'int'774 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'775 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'776 [003] 2 {Parameter} 'ParamBool' -> 'bool'777 [003] {Block}778 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'779 [004] 5 {Line}780 [004] {Code} 'movl $0x7, -0x1c(%rbp)'781 [004] 6 {Line}782 [004] {Code} 'movl $0x7, -0x4(%rbp)'783 [004] {Code} 'jmp 0x6'784 [004] 8 {Line}785 [004] {Code} 'movl -0x14(%rbp), %eax'786 [003] 4 {TypeAlias} 'INTEGER' -> 'int'787 [003] 2 {Line}788 [003] {Code} 'pushq %rbp'789 [003] {Code} 'movq %rsp, %rbp'790 [003] {Code} 'movb %dl, %al'791 [003] {Code} 'movq %rdi, -0x10(%rbp)'792 [003] {Code} 'movl %esi, -0x14(%rbp)'793 [003] {Code} 'andb $0x1, %al'794 [003] {Code} 'movb %al, -0x15(%rbp)'795 [003] 3 {Line}796 [003] {Code} 'testb $0x1, -0x15(%rbp)'797 [003] {Code} 'je 0x13'798 [003] 8 {Line}799 [003] {Code} 'movl %eax, -0x4(%rbp)'800 [003] 9 {Line}801 [003] {Code} 'movl -0x4(%rbp), %eax'802 [003] {Code} 'popq %rbp'803 [003] {Code} 'retq'804 [003] 9 {Line}805 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'806 807On closer inspection, we can see what could be a potential debug issue:808 809.. code-block:: none810 811 [003] {Block}812 [003] 4 {TypeAlias} 'INTEGER' -> 'int'813 814The **'INTEGER'** definition is at level **[003]**, the same lexical815scope as the anonymous **{Block}** ('true' branch for the 'if' statement)816whereas in the original source code the typedef statement is clearly817inside that block, so the **'INTEGER'** definition should also be at818level **[004]** inside the block.819 820SELECT LOGICAL ELEMENTS821"""""""""""""""""""""""822The following prints all *instructions*, *symbols* and *types* that823contain **'inte'** or **'movl'** in their names or types, using a tab824layout and given the number of matches.825 826.. code-block:: none827 828 llvm-debuginfo-analyzer --attribute=level829 --select-nocase --select-regex830 --select=INTe --select=movl831 --report=list832 --print=symbols,types,instructions,summary833 test-dwarf-clang.o834 835 Logical View:836 [000] {File} 'test-dwarf-clang.o'837 838 [001] {CompileUnit} 'test.cpp'839 [003] {Code} 'movl $0x7, -0x1c(%rbp)'840 [003] {Code} 'movl $0x7, -0x4(%rbp)'841 [003] {Code} 'movl %eax, -0x4(%rbp)'842 [003] {Code} 'movl %esi, -0x14(%rbp)'843 [003] {Code} 'movl -0x14(%rbp), %eax'844 [003] {Code} 'movl -0x4(%rbp), %eax'845 [003] 4 {TypeAlias} 'INTEGER' -> 'int'846 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'847 848 -----------------------------849 Element Total Found850 -----------------------------851 Scopes 3 0852 Symbols 4 1853 Types 2 1854 Lines 17 6855 -----------------------------856 Total 26 8857 858COMPARISON MODE859^^^^^^^^^^^^^^^860In this mode :program:`llvm-debuginfo-analyzer` compares logical views861to produce a report with the logical elements that are missing or added.862This a very powerful aid in finding semantic differences in the debug863information produced by different toolchain versions or even completely864different toolchains altogether (For example a compiler producing DWARF865can be directly compared against a completely different compiler that866produces CodeView).867 868Given the previous example we found the above debug information issue869(related to the previous invalid scope location for the **'typedef int870INTEGER'**) by comparing against another compiler.871 872Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern873with the printing mode to obtain the following logical view output.874 875.. code-block:: none876 877 llvm-debuginfo-analyzer --attribute=level878 --select-regex --select-nocase --select=INTe879 --report=list880 --print=symbols,types881 test-dwarf-clang.o test-dwarf-gcc.o882 883 Logical View:884 [000] {File} 'test-dwarf-clang.o'885 886 [001] {CompileUnit} 'test.cpp'887 [003] 4 {TypeAlias} 'INTEGER' -> 'int'888 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'889 890 Logical View:891 [000] {File} 'test-dwarf-gcc.o'892 893 [001] {CompileUnit} 'test.cpp'894 [004] 4 {TypeAlias} 'INTEGER' -> 'int'895 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'896 897The output shows that both objects contain the same elements. But the898**'typedef INTEGER'** is located at different scope level. The GCC899generated object, shows **'4'**, which is the correct value.900 901Note that there is no requirement that GCC must produce identical or902similar DWARF to Clang to allow the comparison. We're only comparing903the semantics. The same case when comparing CodeView debug information904generated by MSVC and Clang.905 906There are 2 comparison methods: logical view and logical elements.907 908LOGICAL VIEW909""""""""""""910It compares the logical view as a whole unit; for a match, each compared911logical element must have the same parents and children.912 913Using the :program:`llvm-debuginfo-analyzer` comparison functionality,914that issue can be seen in a more global context, that can include the915logical view.916 917The output shows in view form the **missing (-), added (+)** elements,918giving more context by swapping the reference and target object files.919 920.. code-block:: none921 922 llvm-debuginfo-analyzer --attribute=level923 --compare=types924 --report=view925 --print=symbols,types926 test-dwarf-clang.o test-dwarf-gcc.o927 928 Reference: 'test-dwarf-clang.o'929 Target: 'test-dwarf-gcc.o'930 931 Logical View:932 [000] {File} 'test-dwarf-clang.o'933 934 [001] {CompileUnit} 'test.cpp'935 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'936 [002] 2 {Function} extern not_inlined 'foo' -> 'int'937 [003] {Block}938 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'939 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'940 [003] 2 {Parameter} 'ParamBool' -> 'bool'941 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'942 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'943 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'944 945The output shows the merging view path (reference and target) with the946missing and added elements.947 948LOGICAL ELEMENTS949""""""""""""""""950It compares individual logical elements without considering if their951parents are the same. For both comparison methods, the equal criteria952includes the name, source code location, type, lexical scope level.953 954.. code-block:: none955 956 llvm-debuginfo-analyzer --attribute=level957 --compare=types958 --report=list959 --print=symbols,types,summary960 test-dwarf-clang.o test-dwarf-gcc.o961 962 Reference: 'test-dwarf-clang.o'963 Target: 'test-dwarf-gcc.o'964 965 (1) Missing Types:966 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'967 968 (1) Added Types:969 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'970 971 ----------------------------------------972 Element Expected Missing Added973 ----------------------------------------974 Scopes 4 0 0975 Symbols 0 0 0976 Types 2 1 1977 Lines 0 0 0978 ----------------------------------------979 Total 6 1 1980 981Changing the *Reference* and *Target* order:982 983.. code-block:: none984 985 llvm-debuginfo-analyzer --attribute=level986 --compare=types987 --report=list988 --print=symbols,types,summary989 test-dwarf-gcc.o test-dwarf-clang.o990 991 Reference: 'test-dwarf-gcc.o'992 Target: 'test-dwarf-clang.o'993 994 (1) Missing Types:995 -[004] 4 {TypeAlias} 'INTEGER' -> 'int'996 997 (1) Added Types:998 +[003] 4 {TypeAlias} 'INTEGER' -> 'int'999 1000 ----------------------------------------1001 Element Expected Missing Added1002 ----------------------------------------1003 Scopes 4 0 01004 Symbols 0 0 01005 Types 2 1 11006 Lines 0 0 01007 ----------------------------------------1008 Total 6 1 11009 1010As the *Reference* and *Target* are switched, the *Added Types* from1011the first case now are listed as *Missing Types*.1012 1013TEST CASE 2 - ASSEMBLER INSTRUCTIONS1014~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1015The below example is used to show different output generated by1016:program:`llvm-debuginfo-analyzer`. We compiled the example for an X861017Codeview and ELF targets with recent versions of Clang, GCC and MSVC1018(-O0 -g) for Windows and Linux.1019 1020.. code-block:: c++1021 1022 1 extern int printf(const char * format, ... );1023 21024 3 int main()1025 4 {1026 5 printf("Hello, World\n");1027 6 return 0;1028 7 }1029 1030These are the logical views that :program:`llvm-debuginfo-analyzer`1031generates for 3 different compilers (MSVC, Clang and GCC), emitting1032different debug information formats (CodeView, DWARF) on Windows and1033Linux.1034 1035.. code-block:: none1036 1037 llvm-debuginfo-analyzer --attribute=level,format,producer1038 --print=lines,instructions1039 hello-world-codeview-clang.o1040 hello-world-codeview-msvc.o1041 hello-world-dwarf-clang.o1042 hello-world-dwarf-gcc.o1043 1044CodeView - Clang (Windows)1045^^^^^^^^^^^^^^^^^^^^^^^^^^1046 1047.. code-block:: none1048 1049 Logical View:1050 [000] {File} 'hello-world-codeview-clang.o' -> COFF-x86-641051 1052 [001] {CompileUnit} 'hello-world.cpp'1053 [002] {Producer} 'clang version 14.0.0'1054 [002] {Function} extern not_inlined 'main' -> 'int'1055 [003] 4 {Line}1056 [003] {Code} 'subq $0x28, %rsp'1057 [003] {Code} 'movl $0x0, 0x24(%rsp)'1058 [003] 5 {Line}1059 [003] {Code} 'leaq (%rip), %rcx'1060 [003] {Code} 'callq 0x0'1061 [003] 6 {Line}1062 [003] {Code} 'xorl %eax, %eax'1063 [003] {Code} 'addq $0x28, %rsp'1064 [003] {Code} 'retq'1065 1066CodeView - MSVC (Windows)1067^^^^^^^^^^^^^^^^^^^^^^^^^1068 1069.. code-block:: none1070 1071 Logical View:1072 [000] {File} 'hello-world-codeview-msvc.o' -> COFF-i3861073 1074 [001] {CompileUnit} 'hello-world.cpp'1075 [002] {Producer} 'Microsoft (R) Optimizing Compiler'1076 [002] {Function} extern not_inlined 'main' -> 'int'1077 [003] 4 {Line}1078 [003] {Code} 'pushl %ebp'1079 [003] {Code} 'movl %esp, %ebp'1080 [003] 5 {Line}1081 [003] {Code} 'pushl $0x0'1082 [003] {Code} 'calll 0x0'1083 [003] {Code} 'addl $0x4, %esp'1084 [003] 6 {Line}1085 [003] {Code} 'xorl %eax, %eax'1086 [003] 7 {Line}1087 [003] {Code} 'popl %ebp'1088 [003] {Code} 'retl'1089 1090DWARF - Clang (Linux)1091^^^^^^^^^^^^^^^^^^^^^1092 1093.. code-block:: none1094 1095 Logical View:1096 [000] {File} 'hello-world-dwarf-clang.o' -> elf64-x86-641097 1098 [001] {CompileUnit} 'hello-world.cpp'1099 [002] {Producer} 'clang version 14.0.0'1100 [002] 3 {Function} extern not_inlined 'main' -> 'int'1101 [003] 4 {Line}1102 [003] {Code} 'pushq %rbp'1103 [003] {Code} 'movq %rsp, %rbp'1104 [003] {Code} 'subq $0x10, %rsp'1105 [003] {Code} 'movl $0x0, -0x4(%rbp)'1106 [003] 5 {Line}1107 [003] {Code} 'movabsq $0x0, %rdi'1108 [003] {Code} 'movb $0x0, %al'1109 [003] {Code} 'callq 0x0'1110 [003] 6 {Line}1111 [003] {Code} 'xorl %eax, %eax'1112 [003] {Code} 'addq $0x10, %rsp'1113 [003] {Code} 'popq %rbp'1114 [003] {Code} 'retq'1115 [003] 6 {Line}1116 1117DWARF - GCC (Linux)1118^^^^^^^^^^^^^^^^^^^1119 1120.. code-block:: none1121 1122 Logical View:1123 [000] {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-641124 1125 [001] {CompileUnit} 'hello-world.cpp'1126 [002] {Producer} 'GNU C++14 9.3.0'1127 [002] 3 {Function} extern not_inlined 'main' -> 'int'1128 [003] 4 {Line}1129 [003] {Code} 'endbr64'1130 [003] {Code} 'pushq %rbp'1131 [003] {Code} 'movq %rsp, %rbp'1132 [003] 5 {Line}1133 [003] {Code} 'leaq (%rip), %rdi'1134 [003] {Code} 'movl $0x0, %eax'1135 [003] {Code} 'callq 0x0'1136 [003] 6 {Line}1137 [003] {Code} 'movl $0x0, %eax'1138 [003] 7 {Line}1139 [003] {Code} 'popq %rbp'1140 [003] {Code} 'retq'1141 [003] 7 {Line}1142 1143The logical views shows the intermixed lines and assembler instructions,1144allowing to compare the code generated by the different toolchains.1145 1146TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF1147~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1148The below example is used to show different output generated by1149:program:`llvm-debuginfo-analyzer`. We compiled the example for an X861150Codeview and ELF targets with recent versions of Clang, GCC and MSVC1151(-O0 -g).1152 1153.. code-block:: c++1154 1155 1 int bar(float Input) { return (int)Input; }1156 21157 3 unsigned foo(char Param) {1158 4 typedef int INT; // ** Definition for INT **1159 5 INT Value = Param;1160 6 {1161 7 typedef float FLOAT; // ** Definition for FLOAT **1162 8 {1163 9 FLOAT Added = Value + Param;1164 10 Value = bar(Added);1165 11 }1166 12 }1167 13 return Value + Param;1168 14 }1169 1170The above test is used to illustrate a scope issue found in the Clang1171compiler:1172`PR44884 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=44884>`_ /1173`PR44229 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/44229>`_1174 1175The lines 4 and 7 contains 2 typedefs, defined at different lexical1176scopes.1177 1178.. code-block:: c++1179 1180 4 typedef int INT;1181 7 typedef float FLOAT;1182 1183These are the logical views that :program:`llvm-debuginfo-analyzer`1184generates for 3 different compilers (MSVC, Clang and GCC), emitting1185different debug information formats (CodeView, DWARF) on different1186platforms.1187 1188.. code-block:: none1189 1190 llvm-debuginfo-analyzer --attribute=level,format,producer1191 --print=symbols,types,lines1192 --output-sort=kind1193 pr-44884-codeview-clang.o1194 pr-44884-codeview-msvc.o1195 pr-44884-dwarf-clang.o1196 pr-44884-dwarf-gcc.o1197 1198CodeView - Clang (Windows)1199^^^^^^^^^^^^^^^^^^^^^^^^^^1200 1201.. code-block:: none1202 1203 Logical View:1204 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-641205 1206 [001] {CompileUnit} 'pr-44884.cpp'1207 [002] {Producer} 'clang version 14.0.0'1208 [002] {Function} extern not_inlined 'bar' -> 'int'1209 [003] {Parameter} 'Input' -> 'float'1210 [003] 1 {Line}1211 [002] {Function} extern not_inlined 'foo' -> 'unsigned'1212 [003] {Block}1213 [004] {Variable} 'Added' -> 'float'1214 [004] 9 {Line}1215 [004] 10 {Line}1216 [003] {Parameter} 'Param' -> 'char'1217 [003] {TypeAlias} 'FLOAT' -> 'float'1218 [003] {TypeAlias} 'INT' -> 'int'1219 [003] {Variable} 'Value' -> 'int'1220 [003] 3 {Line}1221 [003] 5 {Line}1222 [003] 13 {Line}1223 1224CodeView - MSVC (Windows)1225^^^^^^^^^^^^^^^^^^^^^^^^^1226 1227.. code-block:: none1228 1229 Logical View:1230 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i3861231 1232 [001] {CompileUnit} 'pr-44884.cpp'1233 [002] {Producer} 'Microsoft (R) Optimizing Compiler'1234 [002] {Function} extern not_inlined 'bar' -> 'int'1235 [003] {Variable} 'Input' -> 'float'1236 [003] 1 {Line}1237 [002] {Function} extern not_inlined 'foo' -> 'unsigned'1238 [003] {Block}1239 [004] {Block}1240 [005] {Variable} 'Added' -> 'float'1241 [004] {TypeAlias} 'FLOAT' -> 'float'1242 [004] 9 {Line}1243 [004] 10 {Line}1244 [003] {TypeAlias} 'INT' -> 'int'1245 [003] {Variable} 'Param' -> 'char'1246 [003] {Variable} 'Value' -> 'int'1247 [003] 3 {Line}1248 [003] 5 {Line}1249 [003] 13 {Line}1250 [003] 14 {Line}1251 1252DWARF - Clang (Linux)1253^^^^^^^^^^^^^^^^^^^^^1254 1255.. code-block:: none1256 1257 Logical View:1258 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-641259 1260 [001] {CompileUnit} 'pr-44884.cpp'1261 [002] {Producer} 'clang version 14.0.0'1262 [002] 1 {Function} extern not_inlined 'bar' -> 'int'1263 [003] 1 {Parameter} 'Input' -> 'float'1264 [003] 1 {Line}1265 [003] 1 {Line}1266 [003] 1 {Line}1267 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int'1268 [003] {Block}1269 [004] 9 {Variable} 'Added' -> 'FLOAT'1270 [004] 9 {Line}1271 [004] 9 {Line}1272 [004] 9 {Line}1273 [004] 9 {Line}1274 [004] 9 {Line}1275 [004] 10 {Line}1276 [004] 10 {Line}1277 [004] 10 {Line}1278 [004] 13 {Line}1279 [003] 3 {Parameter} 'Param' -> 'char'1280 [003] 7 {TypeAlias} 'FLOAT' -> 'float'1281 [003] 4 {TypeAlias} 'INT' -> 'int'1282 [003] 5 {Variable} 'Value' -> 'INT'1283 [003] 3 {Line}1284 [003] 5 {Line}1285 [003] 5 {Line}1286 [003] 13 {Line}1287 [003] 13 {Line}1288 [003] 13 {Line}1289 [003] 13 {Line}1290 1291DWARF - GCC (Linux)1292^^^^^^^^^^^^^^^^^^^1293 1294.. code-block:: none1295 1296 Logical View:1297 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm1298 1299 [001] {CompileUnit} 'pr-44884.cpp'1300 [002] {Producer} 'GNU C++14 10.2.1 20201103'1301 [002] 1 {Function} extern not_inlined 'bar' -> 'int'1302 [003] 1 {Parameter} 'Input' -> 'float'1303 [003] 1 {Line}1304 [003] 1 {Line}1305 [003] 1 {Line}1306 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int'1307 [003] {Block}1308 [004] {Block}1309 [005] 9 {Variable} 'Added' -> 'FLOAT'1310 [005] 9 {Line}1311 [005] 9 {Line}1312 [005] 9 {Line}1313 [005] 10 {Line}1314 [005] 13 {Line}1315 [004] 7 {TypeAlias} 'FLOAT' -> 'float'1316 [003] 3 {Parameter} 'Param' -> 'char'1317 [003] 4 {TypeAlias} 'INT' -> 'int'1318 [003] 5 {Variable} 'Value' -> 'INT'1319 [003] 3 {Line}1320 [003] 5 {Line}1321 [003] 13 {Line}1322 [003] 14 {Line}1323 [003] 14 {Line}1324 1325From the previous logical views, we can see that the Clang compiler1326emits **both typedefs at the same lexical scope (3)**, which is wrong.1327GCC and MSVC emit correct lexical scope for both typedefs.1328 1329Using the :program:`llvm-debuginfo-analyzer` selection facilities, we1330can produce a simple tabular output showing just the logical types that1331are **Typedef**.1332 1333.. code-block:: none1334 1335 llvm-debuginfo-analyzer --attribute=level,format1336 --output-sort=name1337 --select-types=Typedef1338 --report=list1339 --print=types1340 pr-44884-*.o1341 1342 Logical View:1343 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-641344 1345 [001] {CompileUnit} 'pr_44884.cpp'1346 [003] {TypeAlias} 'FLOAT' -> 'float'1347 [003] {TypeAlias} 'INT' -> 'int'1348 1349 Logical View:1350 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i3861351 1352 [001] {CompileUnit} 'pr_44884.cpp'1353 [004] {TypeAlias} 'FLOAT' -> 'float'1354 [003] {TypeAlias} 'INT' -> 'int'1355 1356 Logical View:1357 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-641358 1359 [001] {CompileUnit} 'pr_44884.cpp'1360 [003] 7 {TypeAlias} 'FLOAT' -> 'float'1361 [003] 4 {TypeAlias} 'INT' -> 'int'1362 1363 Logical View:1364 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm1365 1366 [001] {CompileUnit} 'pr_44884.cpp'1367 [004] 7 {TypeAlias} 'FLOAT' -> 'float'1368 [003] 4 {TypeAlias} 'INT' -> 'int'1369 1370It also shows, that the CodeView debug information does not generate1371source code line numbers for the those logical types. The logical view1372is sorted by the types name.1373 1374TEST CASE 4 - MISSING NESTED ENUMERATIONS1375~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1376The below example is used to show different output generated by1377:program:`llvm-debuginfo-analyzer`. We compiled the example for an X861378Codeview and ELF targets with recent versions of Clang, GCC and MSVC1379(-O0 -g).1380 1381.. code-block:: c++1382 1383 1 struct Struct {1384 2 union Union {1385 3 enum NestedEnum { RED, BLUE };1386 4 };1387 5 Union U;1388 6 };1389 71390 8 Struct S;1391 9 int test() {1392 10 return S.U.BLUE;1393 11 }1394 1395The above test is used to illustrate a scope issue found in the Clang1396compiler:1397`PR46466 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=46466>`_ /1398`PR45811 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/45811>`_1399 1400These are the logical views that :program:`llvm-debuginfo-analyzer`1401generates for 3 different compilers (MSVC, Clang and GCC), emitting1402different debug information formats (CodeView, DWARF) on different1403platforms.1404 1405.. code-block:: none1406 1407 llvm-debuginfo-analyzer --attribute=level,format,producer1408 --output-sort=name1409 --print=symbols,types1410 pr-46466-codeview-clang.o1411 pr-46466-codeview-msvc.o1412 pr-46466-dwarf-clang.o1413 pr-46466-dwarf-gcc.o1414 1415CodeView - Clang (Windows)1416^^^^^^^^^^^^^^^^^^^^^^^^^^1417 1418.. code-block:: none1419 1420 Logical View:1421 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-641422 1423 [001] {CompileUnit} 'pr-46466.cpp'1424 [002] {Producer} 'clang version 14.0.0'1425 [002] {Variable} extern 'S' -> 'Struct'1426 [002] 1 {Struct} 'Struct'1427 [003] {Member} public 'U' -> 'Union'1428 [003] 2 {Union} 'Union'1429 [004] 3 {Enumeration} 'NestedEnum' -> 'int'1430 [005] {Enumerator} 'BLUE' = '0x1'1431 [005] {Enumerator} 'RED' = '0x0'1432 1433CodeView - MSVC (Windows)1434^^^^^^^^^^^^^^^^^^^^^^^^^1435 1436.. code-block:: none1437 1438 Logical View:1439 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i3861440 1441 [001] {CompileUnit} 'pr-46466.cpp'1442 [002] {Producer} 'Microsoft (R) Optimizing Compiler'1443 [002] {Variable} extern 'S' -> 'Struct'1444 [002] 1 {Struct} 'Struct'1445 [003] {Member} public 'U' -> 'Union'1446 [003] 2 {Union} 'Union'1447 [004] 3 {Enumeration} 'NestedEnum' -> 'int'1448 [005] {Enumerator} 'BLUE' = '0x1'1449 [005] {Enumerator} 'RED' = '0x0'1450 1451DWARF - Clang (Linux)1452^^^^^^^^^^^^^^^^^^^^^1453 1454.. code-block:: none1455 1456 Logical View:1457 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-641458 1459 [001] {CompileUnit} 'pr-46466.cpp'1460 [002] {Producer} 'clang version 14.0.0'1461 [002] 8 {Variable} extern 'S' -> 'Struct'1462 [002] 1 {Struct} 'Struct'1463 [003] 5 {Member} public 'U' -> 'Union'1464 1465DWARF - GCC (Linux)1466^^^^^^^^^^^^^^^^^^^1467 1468.. code-block:: none1469 1470 Logical View:1471 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-641472 1473 [001] {CompileUnit} 'pr-46466.cpp'1474 [002] {Producer} 'GNU C++14 9.3.0'1475 [002] 8 {Variable} extern 'S' -> 'Struct'1476 [002] 1 {Struct} 'Struct'1477 [003] 5 {Member} public 'U' -> 'Union'1478 [003] 2 {Union} 'Union'1479 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'1480 [005] {Enumerator} 'BLUE' = '0x1'1481 [005] {Enumerator} 'RED' = '0x0'1482 1483From the previous logical views, we can see that the DWARF debug1484information generated by the Clang compiler does not include any1485references to the enumerators **RED** and **BLUE**. The DWARF1486generated by GCC, CodeView generated by Clang and MSVC, they do1487include such references.1488 1489Using the :program:`llvm-debuginfo-analyzer` selection facilities, we1490can produce a logical view showing just the logical types that are1491**Enumerator** and its parents. The logical view is sorted by the types1492name.1493 1494.. code-block:: none1495 1496 llvm-debuginfo-analyzer --attribute=format,level1497 --output-sort=name1498 --select-types=Enumerator1499 --report=parents1500 --print=types1501 pr-46466-*.o1502 1503.. code-block:: none1504 1505 Logical View:1506 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-641507 1508 [001] {CompileUnit} 'pr-46466.cpp'1509 [002] 1 {Struct} 'Struct'1510 [003] 2 {Union} 'Union'1511 [004] 3 {Enumeration} 'NestedEnum' -> 'int'1512 [005] {Enumerator} 'BLUE' = '0x1'1513 [005] {Enumerator} 'RED' = '0x0'1514 1515 Logical View:1516 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i3861517 1518 [001] {CompileUnit} 'pr-46466.cpp'1519 [002] 1 {Struct} 'Struct'1520 [003] 2 {Union} 'Union'1521 [004] 3 {Enumeration} 'NestedEnum' -> 'int'1522 [005] {Enumerator} 'BLUE' = '0x1'1523 [005] {Enumerator} 'RED' = '0x0'1524 1525 Logical View:1526 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-641527 1528 [001] {CompileUnit} 'pr-46466.cpp'1529 1530 Logical View:1531 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-641532 1533 [001] {CompileUnit} 'pr-46466.cpp'1534 [002] 1 {Struct} 'Struct'1535 [003] 2 {Union} 'Union'1536 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'1537 [005] {Enumerator} 'BLUE' = '0x1'1538 [005] {Enumerator} 'RED' = '0x0'1539 1540Using the :program:`llvm-debuginfo-analyzer` selection facilities, we1541can produce a simple tabular output including a summary for the logical1542types that are **Enumerator**. The logical view is sorted by the types1543name.1544 1545.. code-block:: none1546 1547 llvm-debuginfo-analyzer --attribute=format,level1548 --output-sort=name1549 --select-types=Enumerator1550 --print=types,summary1551 pr-46466-*.o1552 1553.. code-block:: none1554 1555 Logical View:1556 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-641557 1558 [001] {CompileUnit} 'pr-46466.cpp'1559 [005] {Enumerator} 'BLUE' = '0x1'1560 [005] {Enumerator} 'RED' = '0x0'1561 1562 -----------------------------1563 Element Total Found1564 -----------------------------1565 Scopes 5 01566 Symbols 2 01567 Types 6 21568 Lines 0 01569 -----------------------------1570 Total 13 21571 1572 Logical View:1573 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i3861574 1575 [001] {CompileUnit} 'pr-46466.cpp'1576 [005] {Enumerator} 'BLUE' = '0x1'1577 [005] {Enumerator} 'RED' = '0x0'1578 1579 -----------------------------1580 Element Total Found1581 -----------------------------1582 Scopes 5 01583 Symbols 2 01584 Types 7 21585 Lines 0 01586 -----------------------------1587 Total 14 21588 1589 Logical View:1590 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-641591 1592 [001] {CompileUnit} 'pr-46466.cpp'1593 1594 -----------------------------1595 Element Total Found1596 -----------------------------1597 Scopes 4 01598 Symbols 0 01599 Types 0 01600 Lines 0 01601 -----------------------------1602 Total 4 01603 1604 Logical View:1605 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-641606 1607 [001] {CompileUnit} 'pr-46466.cpp'1608 [005] {Enumerator} 'BLUE' = '0x1'1609 [005] {Enumerator} 'RED' = '0x0'1610 1611 -----------------------------1612 Element Total Found1613 -----------------------------1614 Scopes 5 01615 Symbols 0 01616 Types 2 21617 Lines 0 01618 -----------------------------1619 Total 7 21620 1621From the values printed under the **Found** column, we can see that no1622**Types** were found in the DWARF debug information generated by Clang.1623 1624TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE1625~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1626The below example is used to show different output generated by1627:program:`llvm-debuginfo-analyzer`. We compiled the example for an X861628Codeview and ELF targets with recent versions of Clang, GCC and MSVC1629(-O0 -g).1630 1631.. code-block:: c++1632 1633 // definitions.h1634 #ifdef _MSC_VER1635 #define forceinline __forceinline1636 #elif defined(__clang__)1637 #if __has_attribute(__always_inline__)1638 #define forceinline inline __attribute__((__always_inline__))1639 #else1640 #define forceinline inline1641 #endif1642 #elif defined(__GNUC__)1643 #define forceinline inline __attribute__((__always_inline__))1644 #else1645 #define forceinline inline1646 #error1647 #endif1648 1649As the test is dependent on inline compiler options, the above header1650file defines *forceinline*.1651 1652.. code-block:: c++1653 1654 #include "definitions.h"1655 1656.. code-block:: c++1657 1658 1 #include "definitions.h"1659 2 forceinline int InlineFunction(int Param) {1660 3 int Var_1 = Param;1661 4 {1662 5 int Var_2 = Param + Var_1;1663 6 Var_1 = Var_2;1664 7 }1665 8 return Var_1;1666 9 }1667 101668 11 int test(int Param_1, int Param_2) {1669 12 int A = Param_1;1670 13 A += InlineFunction(Param_2);1671 14 return A;1672 15 }1673 1674The above test is used to illustrate a variable issue found in the Clang1675compiler:1676`PR43860 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=43860>`_ /1677`PR43205 (GitHub) <https://github.com/llvm/llvm-project/issues/43205>`_1678 1679These are the logical views that :program:`llvm-debuginfo-analyzer`1680generates for 3 different compilers (MSVC, Clang and GCC), emitting1681different debug information formats (CodeView, DWARF) on different1682platforms.1683 1684.. code-block:: none1685 1686 llvm-debuginfo-analyzer --attribute=level,format,producer1687 --output-sort=name1688 --print=symbols1689 pr-43860-codeview-clang.o1690 pr-43860-codeview-msvc.o1691 pr-43860-dwarf-clang.o1692 pr-43860-dwarf-gcc.o1693 1694CODEVIEW - Clang (Windows)1695^^^^^^^^^^^^^^^^^^^^^^^^^^1696 1697.. code-block:: none1698 1699 Logical View:1700 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-641701 1702 [001] {CompileUnit} 'pr-43860.cpp'1703 [002] {Producer} 'clang version 14.0.0'1704 [002] 2 {Function} inlined 'InlineFunction' -> 'int'1705 [003] {Parameter} '' -> 'int'1706 [002] {Function} extern not_inlined 'test' -> 'int'1707 [003] {Variable} 'A' -> 'int'1708 [003] {InlinedFunction} inlined 'InlineFunction' -> 'int'1709 [004] {Parameter} 'Param' -> 'int'1710 [004] {Variable} 'Var_1' -> 'int'1711 [004] {Variable} 'Var_2' -> 'int'1712 [003] {Parameter} 'Param_1' -> 'int'1713 [003] {Parameter} 'Param_2' -> 'int'1714 1715CODEVIEW - MSVC (Windows)1716^^^^^^^^^^^^^^^^^^^^^^^^^1717 1718.. code-block:: none1719 1720 Logical View:1721 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i3861722 1723 [001] {CompileUnit} 'pr-43860.cpp'1724 [002] {Producer} 'Microsoft (R) Optimizing Compiler'1725 [002] {Function} extern not_inlined 'InlineFunction' -> 'int'1726 [003] {Block}1727 [004] {Variable} 'Var_2' -> 'int'1728 [003] {Variable} 'Param' -> 'int'1729 [003] {Variable} 'Var_1' -> 'int'1730 [002] {Function} extern not_inlined 'test' -> 'int'1731 [003] {Variable} 'A' -> 'int'1732 [003] {Variable} 'Param_1' -> 'int'1733 [003] {Variable} 'Param_2' -> 'int'1734 1735DWARF - Clang (Linux)1736^^^^^^^^^^^^^^^^^^^^^1737 1738.. code-block:: none1739 1740 Logical View:1741 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-641742 1743 [001] {CompileUnit} 'pr-43860.cpp'1744 [002] {Producer} 'clang version 14.0.0'1745 [002] 2 {Function} extern inlined 'InlineFunction' -> 'int'1746 [003] {Block}1747 [004] 5 {Variable} 'Var_2' -> 'int'1748 [003] 2 {Parameter} 'Param' -> 'int'1749 [003] 3 {Variable} 'Var_1' -> 'int'1750 [002] 11 {Function} extern not_inlined 'test' -> 'int'1751 [003] 12 {Variable} 'A' -> 'int'1752 [003] 13 {InlinedFunction} inlined 'InlineFunction' -> 'int'1753 [004] {Block}1754 [005] {Variable} 'Var_2' -> 'int'1755 [004] {Parameter} 'Param' -> 'int'1756 [004] {Variable} 'Var_1' -> 'int'1757 [003] 11 {Parameter} 'Param_1' -> 'int'1758 [003] 11 {Parameter} 'Param_2' -> 'int'1759 1760DWARF - GCC (Linux)1761^^^^^^^^^^^^^^^^^^^1762 1763.. code-block:: none1764 1765 Logical View:1766 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-641767 1768 [001] {CompileUnit} 'pr-43860.cpp'1769 [002] {Producer} 'GNU C++14 9.3.0'1770 [002] 2 {Function} extern declared_inlined 'InlineFunction' -> 'int'1771 [003] {Block}1772 [004] 5 {Variable} 'Var_2' -> 'int'1773 [003] 2 {Parameter} 'Param' -> 'int'1774 [003] 3 {Variable} 'Var_1' -> 'int'1775 [002] 11 {Function} extern not_inlined 'test' -> 'int'1776 [003] 12 {Variable} 'A' -> 'int'1777 [003] 13 {InlinedFunction} declared_inlined 'InlineFunction' -> 'int'1778 [004] {Block}1779 [005] {Variable} 'Var_2' -> 'int'1780 [004] {Parameter} 'Param' -> 'int'1781 [004] {Variable} 'Var_1' -> 'int'1782 [003] 11 {Parameter} 'Param_1' -> 'int'1783 [003] 11 {Parameter} 'Param_2' -> 'int'1784 1785From the previous logical views, we can see that the CodeView debug1786information generated by the Clang compiler shows the variables **Var_1**1787and **Var_2** are at the same lexical scope (**4**) in the function1788**InlineFuction**. The DWARF generated by GCC/Clang and CodeView1789generated by MSVC, show those variables at the correct lexical scope:1790**3** and **4** respectively.1791 1792Using the :program:`llvm-debuginfo-analyzer` selection facilities, we1793can produce a simple tabular output showing just the logical elements1794that have in their name the *var* pattern. The logical view is sorted1795by the variables name.1796 1797.. code-block:: none1798 1799 llvm-debuginfo-analyzer --attribute=level,format1800 --output-sort=name1801 --select-regex --select-nocase --select=Var1802 --report=list1803 --print=symbols1804 pr-43860-*.o1805 1806.. code-block:: none1807 1808 Logical View:1809 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-641810 1811 [001] {CompileUnit} 'pr-43860.cpp'1812 [004] {Variable} 'Var_1' -> 'int'1813 [004] {Variable} 'Var_2' -> 'int'1814 1815 Logical View:1816 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i3861817 1818 [001] {CompileUnit} 'pr-43860.cpp'1819 [003] {Variable} 'Var_1' -> 'int'1820 [004] {Variable} 'Var_2' -> 'int'1821 1822 Logical View:1823 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-641824 1825 [001] {CompileUnit} 'pr-43860.cpp'1826 [004] {Variable} 'Var_1' -> 'int'1827 [003] 3 {Variable} 'Var_1' -> 'int'1828 [005] {Variable} 'Var_2' -> 'int'1829 [004] 5 {Variable} 'Var_2' -> 'int'1830 1831 Logical View:1832 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-641833 1834 [001] {CompileUnit} 'pr-43860.cpp'1835 [004] {Variable} 'Var_1' -> 'int'1836 [003] 3 {Variable} 'Var_1' -> 'int'1837 [005] {Variable} 'Var_2' -> 'int'1838 [004] 5 {Variable} 'Var_2' -> 'int'1839 1840It also shows, that the CodeView debug information does not generate1841source code line numbers for the those logical symbols. The logical1842view is sorted by the types name.1843 1844TEST CASE 6 - FULL LOGICAL VIEW1845~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1846For advanced users, :program:`llvm-debuginfo-analyzer` can display low1847level information that includes offsets within the debug information1848section, debug location operands, linkage names, etc.1849 1850.. code-block:: none1851 1852 llvm-debuginfo-analyzer --attribute=all1853 --print=all1854 test-dwarf-clang.o1855 1856 Logical View:1857 [0x0000000000][000] {File} 'test-dwarf-clang.o' -> elf64-x86-641858 1859 [0x000000000b][001] {CompileUnit} 'test.cpp'1860 [0x000000000b][002] {Producer} 'clang version 12.0.0'1861 {Directory} ''1862 {File} 'test.cpp'1863 {Public} 'foo' [0x0000000000:0x000000003a]1864 [0x000000000b][002] {Range} Lines 2:9 [0x0000000000:0x000000003a]1865 [0x00000000bc][002] {BaseType} 'bool'1866 [0x0000000099][002] {BaseType} 'int'1867 [0x00000000b5][002] {BaseType} 'unsigned int'1868 1869 [0x00000000a0][002] {Source} '/test.cpp'1870 [0x00000000a0][002] 1 {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'1871 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'1872 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a]1873 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb'1874 [0x0000000071][003] {Block}1875 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f]1876 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'1877 [0x000000007e][005] {Coverage} 100.00%1878 [0x000000007f][005] {Location}1879 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]1880 [0x000000001c][004] 5 {Line} {NewStatement} '/test.cpp'1881 [0x000000001c][004] {Code} 'movl $0x7, -0x1c(%rbp)'1882 [0x0000000023][004] 6 {Line} {NewStatement} '/test.cpp'1883 [0x0000000023][004] {Code} 'movl $0x7, -0x4(%rbp)'1884 [0x000000002a][004] {Code} 'jmp 0x6'1885 [0x000000002f][004] 8 {Line} {NewStatement} '/test.cpp'1886 [0x000000002f][004] {Code} 'movl -0x14(%rbp), %eax'1887 [0x0000000063][003] 2 {Parameter} 'ParamBool' -> [0x00000000bc]'bool'1888 [0x0000000063][004] {Coverage} 100.00%1889 [0x0000000064][004] {Location}1890 [0x0000000064][005] {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]1891 [0x0000000047][003] 2 {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'1892 [0x0000000047][004] {Coverage} 100.00%1893 [0x0000000048][004] {Location}1894 [0x0000000048][005] {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]1895 [0x0000000055][003] 2 {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'1896 [0x0000000055][004] {Coverage} 100.00%1897 [0x0000000056][004] {Location}1898 [0x0000000056][005] {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]1899 [0x000000008d][003] 4 {TypeAlias} 'INTEGER' -> [0x0000000099]'int'1900 [0x0000000000][003] 2 {Line} {NewStatement} '/test.cpp'1901 [0x0000000000][003] {Code} 'pushq %rbp'1902 [0x0000000001][003] {Code} 'movq %rsp, %rbp'1903 [0x0000000004][003] {Code} 'movb %dl, %al'1904 [0x0000000006][003] {Code} 'movq %rdi, -0x10(%rbp)'1905 [0x000000000a][003] {Code} 'movl %esi, -0x14(%rbp)'1906 [0x000000000d][003] {Code} 'andb $0x1, %al'1907 [0x000000000f][003] {Code} 'movb %al, -0x15(%rbp)'1908 [0x0000000012][003] 3 {Line} {NewStatement} {PrologueEnd} '/test.cpp'1909 [0x0000000012][003] {Code} 'testb $0x1, -0x15(%rbp)'1910 [0x0000000016][003] {Code} 'je 0x13'1911 [0x0000000032][003] 8 {Line} '/test.cpp'1912 [0x0000000032][003] {Code} 'movl %eax, -0x4(%rbp)'1913 [0x0000000035][003] 9 {Line} {NewStatement} '/test.cpp'1914 [0x0000000035][003] {Code} 'movl -0x4(%rbp), %eax'1915 [0x0000000038][003] {Code} 'popq %rbp'1916 [0x0000000039][003] {Code} 'retq'1917 [0x000000003a][003] 9 {Line} {NewStatement} {EndSequence} '/test.cpp'1918 1919 -----------------------------1920 Element Total Printed1921 -----------------------------1922 Scopes 3 31923 Symbols 4 41924 Types 5 51925 Lines 25 251926 -----------------------------1927 Total 37 371928 1929 Scope Sizes:1930 189 (100.00%) : [0x000000000b][001] {CompileUnit} 'test.cpp'1931 110 ( 58.20%) : [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'1932 27 ( 14.29%) : [0x0000000071][003] {Block}1933 1934 Totals by lexical level:1935 [001]: 189 (100.00%)1936 [002]: 110 ( 58.20%)1937 [003]: 27 ( 14.29%)1938 1939The **Scope Sizes** table shows the contribution in bytes to the debug1940information by each scope, which can be used to determine unexpected1941size changes in the DWARF sections between different versions of the1942same toolchain.1943 1944.. code-block:: none1945 1946 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'1947 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a]1948 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb'1949 [0x0000000071][003] {Block}1950 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f]1951 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'1952 [0x000000007e][005] {Coverage} 100.00%1953 [0x000000007f][005] {Location}1954 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]1955 1956The **{Range}** attribute describe the line ranges for a logical scope.1957For this case, the function **foo** is within the lines **2** and **9**.1958 1959The **{Coverage}** and **{Location}** attributes describe the debug1960location and coverage for logical symbols. For optimized code, the1961coverage value decreases and it affects the program debuggability.1962 1963WEBASSEMBLY SUPPORT1964~~~~~~~~~~~~~~~~~~~1965The below example is used to show the WebAssembly output generated by1966:program:`llvm-debuginfo-analyzer`. We compiled the example for a1967WebAssembly 32-bit target with Clang (-O0 -g --target=wasm32):1968 1969.. code-block:: c++1970 1971 1 using INTPTR = const int *;1972 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {1973 3 if (ParamBool) {1974 4 typedef int INTEGER;1975 5 const INTEGER CONSTANT = 7;1976 6 return CONSTANT;1977 7 }1978 8 return ParamUnsigned;1979 9 }1980 1981PRINT BASIC DETAILS1982^^^^^^^^^^^^^^^^^^^1983The following command prints basic details for all the logical elements1984sorted by the debug information internal offset; it includes its lexical1985level and debug info format.1986 1987.. code-block:: none1988 1989 llvm-debuginfo-analyzer --attribute=level,format1990 --output-sort=offset1991 --print=scopes,symbols,types,lines,instructions1992 test-clang.o1993 1994or1995 1996.. code-block:: none1997 1998 llvm-debuginfo-analyzer --attribute=level,format1999 --output-sort=offset2000 --print=elements2001 test-clang.o2002 2003Each row represents an element that is present within the debug2004information. The first column represents the scope level, followed by2005the associated line number (if any), and finally the description of2006the element.2007 2008.. code-block:: none2009 2010 Logical View:2011 [000] {File} 'test-clang.o' -> WASM2012 2013 [001] {CompileUnit} 'test.cpp'2014 [002] 2 {Function} extern not_inlined 'foo' -> 'int'2015 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'2016 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'2017 [003] 2 {Parameter} 'ParamBool' -> 'bool'2018 [003] {Block}2019 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'2020 [004] 5 {Line}2021 [004] {Code} 'i32.const 7'2022 [004] {Code} 'local.set 10'2023 [004] {Code} 'local.get 5'2024 [004] {Code} 'local.get 10'2025 [004] {Code} 'i32.store 12'2026 [004] 6 {Line}2027 [004] {Code} 'i32.const 7'2028 [004] {Code} 'local.set 11'2029 [004] {Code} 'local.get 5'2030 [004] {Code} 'local.get 11'2031 [004] {Code} 'i32.store 28'2032 [004] {Code} 'br 1'2033 [004] - {Line}2034 [004] {Code} 'end'2035 [003] 4 {TypeAlias} 'INTEGER' -> 'int'2036 [003] 2 {Line}2037 [003] {Code} 'nop'2038 [003] {Code} 'end'2039 [003] {Code} 'i64.div_s'2040 [003] {Code} 'global.get 0'2041 [003] {Code} 'local.set 3'2042 [003] {Code} 'i32.const 32'2043 [003] {Code} 'local.set 4'2044 [003] {Code} 'local.get 3'2045 [003] {Code} 'local.get 4'2046 [003] {Code} 'i32.sub'2047 [003] {Code} 'local.set 5'2048 [003] {Code} 'local.get 5'2049 [003] {Code} 'local.get 0'2050 [003] {Code} 'i32.store 24'2051 [003] {Code} 'local.get 5'2052 [003] {Code} 'local.get 1'2053 [003] {Code} 'i32.store 20'2054 [003] {Code} 'local.get 2'2055 [003] {Code} 'local.set 6'2056 [003] {Code} 'local.get 5'2057 [003] {Code} 'local.get 6'2058 [003] {Code} 'i32.store8 19'2059 [003] 3 {Line}2060 [003] {Code} 'local.get 5'2061 [003] {Code} 'i32.load8_u 19'2062 [003] {Code} 'local.set 7'2063 [003] 3 {Line}2064 [003] {Code} 'i32.const 1'2065 [003] {Code} 'local.set 8'2066 [003] {Code} 'local.get 7'2067 [003] {Code} 'local.get 8'2068 [003] {Code} 'i32.and'2069 [003] {Code} 'local.set 9'2070 [003] {Code} 'block'2071 [003] {Code} 'block'2072 [003] {Code} 'local.get 9'2073 [003] {Code} 'i32.eqz'2074 [003] {Code} 'br_if 0'2075 [003] 8 {Line}2076 [003] {Code} 'local.get 5'2077 [003] {Code} 'i32.load 20'2078 [003] {Code} 'local.set 12'2079 [003] 8 {Line}2080 [003] {Code} 'local.get 5'2081 [003] {Code} 'local.get 12'2082 [003] {Code} 'i32.store 28'2083 [003] - {Line}2084 [003] {Code} 'end'2085 [003] 9 {Line}2086 [003] {Code} 'local.get 5'2087 [003] {Code} 'i32.load 28'2088 [003] {Code} 'local.set 13'2089 [003] {Code} 'local.get 13'2090 [003] {Code} 'return'2091 [003] {Code} 'end'2092 [003] 9 {Line}2093 [003] {Code} 'unreachable'2094 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'2095 2096SELECT LOGICAL ELEMENTS2097^^^^^^^^^^^^^^^^^^^^^^^2098The following prints all *instructions*, *symbols* and *types* that2099contain **'block'** or **'.store'** in their names or types, using a tab2100layout and given the number of matches.2101 2102.. code-block:: none2103 2104 llvm-debuginfo-analyzer --attribute=level2105 --select-nocase --select-regex2106 --select=BLOCK --select=.store2107 --report=list2108 --print=symbols,types,instructions,summary2109 test-clang.o2110 2111 Logical View:2112 [000] {File} 'test-clang.o'2113 2114 [001] {CompileUnit} 'test.cpp'2115 [003] {Code} 'block'2116 [003] {Code} 'block'2117 [004] {Code} 'i32.store 12'2118 [003] {Code} 'i32.store 20'2119 [003] {Code} 'i32.store 24'2120 [004] {Code} 'i32.store 28'2121 [003] {Code} 'i32.store 28'2122 [003] {Code} 'i32.store8 19'2123 2124 -----------------------------2125 Element Total Printed2126 -----------------------------2127 Scopes 3 02128 Symbols 4 02129 Types 2 02130 Lines 62 82131 -----------------------------2132 Total 71 82133 2134COMPARISON MODE2135^^^^^^^^^^^^^^^2136Given the previous example we found the above debug information issue2137(related to the previous invalid scope location for the **'typedef int2138INTEGER'**) by comparing against another compiler.2139 2140Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern2141with the printing mode to obtain the following logical view output.2142 2143.. code-block:: none2144 2145 llvm-debuginfo-analyzer --attribute=level2146 --select-regex --select-nocase --select=INTe2147 --report=list2148 --print=symbols,types2149 test-clang.o test-dwarf-gcc.o2150 2151 Logical View:2152 [000] {File} 'test-clang.o'2153 2154 [001] {CompileUnit} 'test.cpp'2155 [003] 4 {TypeAlias} 'INTEGER' -> 'int'2156 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'2157 2158 Logical View:2159 [000] {File} 'test-dwarf-gcc.o'2160 2161 [001] {CompileUnit} 'test.cpp'2162 [004] 4 {TypeAlias} 'INTEGER' -> 'int'2163 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'2164 2165The output shows that both objects contain the same elements. But the2166**'typedef INTEGER'** is located at different scope level. The GCC2167generated object, shows **'4'**, which is the correct value.2168 2169There are 2 comparison methods: logical view and logical elements.2170 2171LOGICAL VIEW2172""""""""""""2173It compares the logical view as a whole unit; for a match, each compared2174logical element must have the same parents and children.2175 2176The output shows in view form the **missing (-), added (+)** elements,2177giving more context by swapping the reference and target object files.2178 2179.. code-block:: none2180 2181 llvm-debuginfo-analyzer --attribute=level2182 --compare=types2183 --report=view2184 --print=symbols,types2185 test-clang.o test-dwarf-gcc.o2186 2187 Reference: 'test-clang.o'2188 Target: 'test-dwarf-gcc.o'2189 2190 Logical View:2191 [000] {File} 'test-clang.o'2192 2193 [001] {CompileUnit} 'test.cpp'2194 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'2195 [002] 2 {Function} extern not_inlined 'foo' -> 'int'2196 [003] {Block}2197 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'2198 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'2199 [003] 2 {Parameter} 'ParamBool' -> 'bool'2200 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'2201 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'2202 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'2203 2204The output shows the merging view path (reference and target) with the2205missing and added elements.2206 2207LOGICAL ELEMENTS2208""""""""""""""""2209It compares individual logical elements without considering if their2210parents are the same. For both comparison methods, the equal criteria2211includes the name, source code location, type, lexical scope level.2212 2213.. code-block:: none2214 2215 llvm-debuginfo-analyzer --attribute=level2216 --compare=types2217 --report=list2218 --print=symbols,types,summary2219 test-clang.o test-dwarf-gcc.o2220 2221 Reference: 'test-clang.o'2222 Target: 'test-dwarf-gcc.o'2223 2224 (1) Missing Types:2225 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'2226 2227 (1) Added Types:2228 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'2229 2230 ----------------------------------------2231 Element Expected Missing Added2232 ----------------------------------------2233 Scopes 4 0 02234 Symbols 0 0 02235 Types 2 1 12236 Lines 0 0 02237 ----------------------------------------2238 Total 6 1 12239 2240Changing the *Reference* and *Target* order:2241 2242.. code-block:: none2243 2244 llvm-debuginfo-analyzer --attribute=level2245 --compare=types2246 --report=list2247 --print=symbols,types,summary2248 test-dwarf-gcc.o test-clang.o2249 2250 Reference: 'test-dwarf-gcc.o'2251 Target: 'test-clang.o'2252 2253 (1) Missing Types:2254 -[004] 4 {TypeAlias} 'INTEGER' -> 'int'2255 2256 (1) Added Types:2257 +[003] 4 {TypeAlias} 'INTEGER' -> 'int'2258 2259 ----------------------------------------2260 Element Expected Missing Added2261 ----------------------------------------2262 Scopes 4 0 02263 Symbols 0 0 02264 Types 2 1 12265 Lines 0 0 02266 ----------------------------------------2267 Total 6 1 12268 2269As the *Reference* and *Target* are switched, the *Added Types* from2270the first case now are listed as *Missing Types*.2271 2272EXIT STATUS2273-----------2274:program:`llvm-debuginfo-analyzer` returns 0 if the input files were2275parsed and printed successfully. Otherwise, it returns 1.2276 2277LIMITATIONS AND KNOWN ISSUES2278----------------------------2279See :download:`Limitations <../../tools/llvm-debuginfo-analyzer/README.md>`.2280 2281SEE ALSO2282--------2283:manpage:`llvm-dwarfdump`2284