1llvm-debuginfo-analyzer - Print a logical representation of low-level debug information. 2======================================================================================== 3 4.. program:: llvm-debuginfo-analyzer 5 6.. contents:: 7 :local: 8 9SYNOPSIS 10-------- 11:program:`llvm-debuginfo-analyzer` [*options*] [*filename ...*] 12 13DESCRIPTION 14----------- 15:program:`llvm-debuginfo-analyzer` parses debug and text sections in 16binary object files and prints their contents in a logical view, which 17is a human readable representation that closely matches the structure 18of the original user source code. Supported object file formats include 19ELF, Mach-O, WebAssembly, PDB and COFF. 20 21The **logical view** abstracts the complexity associated with the 22different low-level representations of the debugging information that 23is embedded in the object file. :program:`llvm-debuginfo-analyzer` 24produces a canonical view of the debug information regardless of how it 25is formatted. The same logical view will be seen regardless of object 26file format, assuming the debug information correctly represents the 27same original source code. 28 29The logical view includes the following **logical elements**: *type*, 30*scope*, *symbol* and *line*, which are the basic software elements used 31in the C/C++ programming language. Each logical element has a set of 32**attributes**, such as *types*, *classes*, *functions*, *variables*, 33*parameters*, etc. The :option:`--attribute` can be used to specify which 34attributes to include when printing a logical element. A logical element 35may have a **kind** that describes specific types of elements. For 36instance, a *scope* could have a kind value of *function*, *class*, 37*namespace*. 38 39:program:`llvm-debuginfo-analyzer` defaults to print a pre-defined 40layout of logical elements and attributes. The command line options can 41be used to control the printed elements (:option:`--print`), using a 42specific layout (:option:`--report`), matching a given pattern 43(:option:`--select`, :option:`--select-offsets`). Also, the output can 44be 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 logical 49views (:option:`--compare`), to find differences and identify possible 50debug information syntax issues (:option:`--warning`) in any object file. 51 52OPTIONS 53------- 54:program:`llvm-debuginfo-analyzer` options are separated into several 55categories, 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 when 59 printing an element. 60 * :ref:`print_` - Specify which elements will be included when printing 61 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 to 65 select which elements to print. 66 * :ref:`compare_` - Compare logical views and print missing and/or 67 added elements. 68 * :ref:`warning_` - Print the warnings detected during the creation 69 of the view. 70 * :ref:`internal_` - Internal analysis of the logical view. 71 72.. _general_: 73 74GENERAL 75~~~~~~~ 76This section describes the standard help options, used to display the 77usage, version, response files, etc. 78 79.. option:: -h, --help 80 81 Show help and usage for this command. (--help-hidden for more). 82 83.. option:: --help-list 84 85 Show help and usage for this command without grouping the options 86 into categories (--help-list-hidden for more). 87 88.. option:: --help-hidden 89 90 Display all available options. 91 92.. option:: --print-all-options 93 94 Print all option values after command line parsing. 95 96.. option:: --print-options 97 98 Print non-default options after command line parsing 99 100.. option:: --version 101 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 116ATTRIBUTES 117~~~~~~~~~~ 118The following options enable attributes given for the printed elements. 119The attributes are divided in categories based on the type of data being 120added, 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:: text 129 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 a 135 logical element. They help to identify the lexical scope level; the 136 element visibility across modules (global, local); the toolchain name 137 that produced the binary file. 138 139 .. code-block:: text 140 141 =global: Element referenced across Compile Units. 142 =format: Object file format name. 143 =level: Lexical scope level (File=0, Compile Unit=1). 144 =local: Element referenced only in the Compile Unit. 145 =producer: Toolchain identification name. 146 147 The following attributes describe files and directory names from the 148 user source code, where the elements are declared or defined; functions 149 with public visibility across modules. These options allow to map the 150 elements to their user code location, for cross references purposes. 151 152 .. code-block:: text 153 154 =directories: Directories referenced in the debug information. 155 =filename: Filename where the element is defined. 156 =files: Files referenced in the debug information. 157 =pathname: Pathname where the object is defined. 158 =publics: Function names that are public. 159 160 The following attributes describe additional logical element source 161 transformations, in order to display built-in types (int, bool, etc.); 162 parameters and arguments used during template instantiation; parent 163 name hierarchy; array dimensions information; compiler generated 164 elements and the underlying types associated with the types aliases. 165 166 .. code-block:: text 167 168 =argument: Template parameters replaced by its arguments. 169 =base: Base types (int, bool, etc.). 170 =generated: Compiler generated elements. 171 =encoded: Template arguments encoded in the template name. 172 =qualified: The element type include parents in its name. 173 =reference: Element declaration and definition references. 174 =subrange: Subrange encoding information for arrays. 175 =typename: Template parameters. 176 =underlying: Underlying type for type definitions. 177 178 The following attributes describe the debug location information for 179 a symbol or scope. It includes the symbol percentage coverage and any 180 gaps within the location layout; ranges determining the code sections 181 attached to a function. When descriptors are used, the target processor 182 registers are displayed. 183 184 .. code-block:: text 185 186 =coverage: Symbol location coverage. 187 =gaps: Missing debug location (gaps). 188 =location: Symbol debug location. 189 =range: Debug location ranges. 190 =register: Processor register names. 191 192 The following attributes are associated with low level details, such 193 as: offsets in the binary file; discriminators added to the lines of 194 inlined functions in order to distinguish specific instances; debug 195 lines state machine registers; elements discarded by the compiler 196 (inlining) or by the linker optimizations (dead-stripping); system 197 compile units generated by the MS toolchain in PDBs. 198 199 .. code-block:: text 200 201 =discarded: Discarded elements by the linker. 202 =discriminator: Discriminators for inlined function instances. 203 =inserted: Generated inlined abstract references. 204 =linkage: Object file linkage name. 205 =offset: Debug information offset. 206 =qualifier: Line qualifiers (Newstatement, BasicBlock, etc). 207 =zero: Zero line numbers. 208 209 The following attribute described specific information for the **PE/COFF** 210 file format. It includes MS runtime types. 211 212 .. code-block:: text 213 214 =system: Display PDB's MS system elements. 215 216 The above attributes are grouped into *standard* and *extended* 217 categories that can be enabled. 218 219 The *standard* group, contains those attributes that add sufficient 220 information to describe a logical element and that can cover the 221 normal situations while dealing with debug information. 222 223 .. code-block:: text 224 225 =base 226 =coverage 227 =directories 228 =discriminator 229 =filename 230 =files 231 =format 232 =level 233 =producer 234 =publics 235 =range 236 =reference 237 =zero 238 239 The *extended* group, contains those attributes that require a more 240 extended knowledge about debug information. They are intended when a 241 lower level of detail is required. 242 243 .. code-block:: text 244 245 =argument 246 =discarded 247 =encoded 248 =gaps 249 =generated 250 =global 251 =inserted 252 =linkage 253 =local 254 =location 255 =offset 256 =operation 257 =pathname 258 =qualified 259 =qualifier 260 =register 261 =subrange 262 =system 263 =typename 264 265.. _print_: 266 267PRINT 268~~~~~ 269The following options describe the elements to print. The layout used 270is determined by the :option:`--report`. In the tree layout, all the 271elements have their enclosing lexical scopes printed, even when not 272explicitly specified. 273 274.. option:: --print=<value[,value,...]> 275 276 With **value** being one of the options in the following lists. 277 278 .. code-block:: text 279 280 =all: Include all the below attributes. 281 282 The following options print the requested elements; in the case of any 283 given select conditions (:option:`--select`), only those elements that 284 match them, will be printed. The **elements** value is a convenient 285 way to specify instructions, lines, scopes, symbols and types all at 286 once. 287 288 .. code-block:: text 289 290 =elements: Instructions, lines, scopes, symbols and types. 291 =instructions: Assembler instructions for code sections. 292 =lines: Source lines referenced in the debug information. 293 =scopes: Lexical blocks (function, class, namespace, etc). 294 =symbols: Symbols (variable, member, parameter, etc). 295 =types: Types (pointer, reference, type alias, etc). 296 297 The following options print information, collected during the creation 298 of the elements, such as: scope contributions to the debug information; 299 summary of elements created, printed or matched (:option:`--select`); 300 warnings produced during the view creation. 301 302 .. code-block:: text 303 304 =sizes: Debug Information scopes contributions. 305 =summary: Summary of elements allocated, selected or printed. 306 =warnings: Warnings detected. 307 308 Note: The **--print=sizes** option is ELF specific. 309 310.. _output_: 311 312OUTPUT 313~~~~~~ 314The following options describe how to control the output generated when 315printing the logical elements. 316 317.. option:: --output-file=<path> 318 319 Redirect the output to a file specified by <path>, where - is the 320 standard output stream. 321 322:program:`llvm-debuginfo-analyzer` has the concept of **split view**. 323When redirecting the output from a complex binary format, it is 324**divided** into individual files, each one containing the logical view 325output for a single compilation unit. 326 327.. option:: --output-folder=<name> 328 329 The folder to write a file per compilation unit when **--output=split** 330 is specified. 331 332.. option:: --output-level=<level> 333 334 Only print elements up to the given **lexical level** value. The input 335 file is at lexical level zero and a compilation unit is at lexical level 336 one. 337 338.. option:: --output=<value[,value,...]> 339 340 With **value** being one of the options in the following lists. 341 342 .. code-block:: text 343 344 =all: Include all the below outputs. 345 346 .. code-block:: text 347 348 =json: Use JSON as the output format (Not implemented). 349 =split: Split the output by Compile Units. 350 =text: Use a free form text output. 351 352.. option:: --output-sort=<key> 353 354 Primary key when ordering the elements in the output (default: line). 355 Sorting by logical element kind, requires be familiarity with the 356 element kind selection options (:option:`--select-lines`, 357 :option:`--select-scopes`, :option:`--select-symbols`, 358 :option:`--select-types`), as those options describe the different 359 logical element kinds. 360 361 .. code-block:: text 362 363 =kind: Sort by element kind. 364 =line: Sort by element line number. 365 =name: Sort by element name. 366 =offset: Sort by element offset. 367 368.. _report_: 369 370REPORT 371~~~~~~ 372Depending on the task being executed (print, compare, select), several 373layouts are supported to display the elements in a more suitable way, 374to make the output easier to understand. 375 376.. option:: --report=<value[,value,...]> 377 378 With **value** being one of the options in the following list. 379 380 .. code-block:: text 381 382 =all: Include all the below reports. 383 384 .. code-block:: text 385 386 =children: Elements and children are displayed in a tree format. 387 =list: Elements are displayed in a tabular format. 388 =parents: Elements and parents are displayed in a tree format. 389 =view: Elements, parents and children are displayed in a tree format. 390 391The **list** layout presents the logical elements in a tabular form 392without any parent-child relationship. This may be the preferred way to 393display elements that match specific conditions when comparing logical 394views, making it easier to find differences. 395 396The **children**, **parents** and **view** layout displays the elements 397in a tree format, with the scopes representing their nodes, and types, 398symbols, lines and other scopes representing the children. The layout 399shows the lexical scoping relationship between elements, with the binary 400file being the tree root (level 0) and each compilation unit being a 401child (level 1). 402 403The **children** layout includes the elements that match any given 404criteria (:option:`--select`) or (:option:`--compare`) and its children. 405 406The **parents** layout includes the elements that match any given 407criteria (:option:`--select`) or (:option:`--compare`) and its parents. 408 409The combined **view** layout includes the elements that match any given 410criteria (:option:`--select`) or (:option:`--compare`), its parents 411and children. 412 413**Notes**: 414 4151. When a selection criteria (:option:`--select`) is specified with no 416 report option, the **list** layout is selected. 4172. The comparison mode always uses the **view** layout. 418 419.. _select_: 420 421SELECTION 422~~~~~~~~~ 423When printing an element, different data can be included and it varies 424(:option:`--attribute`) from data directly associated with the binary 425file (offset) to high level details such as coverage, lexical scope 426level, location. As the printed output can reach a considerable size, 427several selection options, enable printing of specific elements. 428 429The pattern matching can ignore the case (:option:`--select-nocase`) 430and be extended to use regular expressions (:option:`--select-regex`). 431 432ELEMENTS 433^^^^^^^^ 434The following options allow printing of elements that match the given 435<pattern>, offset <value> or an element <condition>. 436 437.. option:: --select=<pattern> 438 439 Print all elements whose name or line number matches the given <pattern>. 440 441.. option:: --select-offsets=<value[,value,...]> 442 443 Print all elements whose offset matches the given values. See 444 :option:`--attribute` option. 445 446.. option:: --select-elements=<condition[,condition,...]> 447 448 Print all elements that satisfy the given <condition>. With **condition** 449 being one of the options in the following list. 450 451 .. code-block:: text 452 453 =discarded: Discarded elements by the linker. 454 =global: Element referenced across Compile Units. 455 =optimized: Optimized inlined abstract references. 456 457.. option:: --select-nocase 458 459 Pattern matching is case-insensitive when using :option:`--select`. 460 461.. option:: --select-regex 462 463 Treat any <pattern> strings as regular expressions when selecting with 464 :option:`--select` option. If :option:`--select-nocase` is specified, 465 the regular expression becomes case-insensitive. 466 467If the <pattern> criteria is too general, a more selective option can 468be specified to target a particular category of elements: 469lines (:option:`--select-lines`), scopes (:option:`--select-scopes`), 470symbols (:option:`--select-symbols`) and types (:option:`--select-types`). 471 472These options require knowledge of the debug information format (DWARF, 473CodeView), as the given **kind** describes a very specific type 474of element. 475 476LINES 477^^^^^ 478The following options allow printing of lines that match the given <kind>. 479The given criteria describes the debug line state machine registers. 480 481.. option:: --select-lines=<kind[,kind,...]> 482 483 With **kind** being one of the options in the following list. 484 485 .. code-block:: text 486 487 =AlwaysStepInto: marks an always step into. 488 =BasicBlock: Marks a new basic block. 489 =Discriminator: Line that has a discriminator. 490 =EndSequence: Marks the end in the sequence of lines. 491 =EpilogueBegin: Marks the start of a function epilogue. 492 =LineDebug: Lines that correspond to debug lines. 493 =LineAssembler: Lines that correspond to disassembly text. 494 =NeverStepInto: marks a never step into. 495 =NewStatement: Marks a new statement. 496 =PrologueEnd: Marks the end of a function prologue. 497 498SCOPES 499^^^^^^ 500The following options allow printing of scopes that match the given <kind>. 501 502.. option:: --select-scopes=<kind[,kind,...]> 503 504 With **kind** being one of the options in the following list. 505 506 .. code-block:: text 507 508 =Aggregate: A class, structure or union. 509 =Array: An array. 510 =Block: A generic block (lexical block or exception block). 511 =CallSite: A call site. 512 =CatchBlock: An exception block. 513 =Class: A class. 514 =CompileUnit: A compile unit. 515 =EntryPoint: A subroutine entry point. 516 =Enumeration: An enumeration. 517 =Function: A function. 518 =FunctionType: A function pointer. 519 =InlinedFunction: An inlined function. 520 =Label: A label. 521 =LexicalBlock: A lexical block. 522 =Namespace: A namespace. 523 =Root: The element representing the main scope. 524 =Structure: A structure. 525 =Subprogram: A subprogram. 526 =Template: A template definition. 527 =TemplateAlias: A template alias. 528 =TemplatePack: A template pack. 529 =TryBlock: An exception try block. 530 =Union: A union. 531 532SYMBOLS 533^^^^^^^ 534The following options allow printing of symbols that match the given <kind>. 535 536.. option:: --select-symbols=<kind[,kind,...]> 537 538 With **kind** being one of the options in the following list. 539 540 .. code-block:: text 541 542 =CallSiteParameter: A call site parameter. 543 =Constant: A constant symbol. 544 =Inheritance: A base class. 545 =Member: A member class. 546 =Parameter: A parameter to function. 547 =Unspecified: Unspecified parameters to function. 548 =Variable: A variable. 549 550TYPES 551^^^^^ 552The following options allow printing of types that match the given <kind>. 553 554.. option:: --select-types=<kind[,kind,...]> 555 556 With **kind** being one of the options in the following list. 557 558 .. code-block:: text 559 560 =Base: Base type (integer, boolean, etc). 561 =Const: Constant specifier. 562 =Enumerator: Enumerator. 563 =Import: Import declaration. 564 =ImportDeclaration: Import declaration. 565 =ImportModule: Import module. 566 =Pointer: Pointer type. 567 =PointerMember: Pointer to member function. 568 =Reference: Reference type. 569 =Restrict: Restrict specifier. 570 =RvalueReference: R-value reference. 571 =Subrange: Array subrange. 572 =TemplateParam: Template parameter. 573 =TemplateTemplateParam: Template template parameter. 574 =TemplateTypeParam: Template type parameter. 575 =TemplateValueParam: Template value parameter. 576 =Typedef: Type definition. 577 =Unspecified: Unspecified type. 578 =Volatile: Volatile specifier. 579 580.. _compare_: 581 582COMPARE 583~~~~~~~ 584When dealing with debug information, there are situations when the 585printing of the elements is not the correct approach. That is the case, 586when we are interested in the effects caused by different versions of 587the same toolchain, or the impact of specific compiler optimizations. 588 589For those cases, we are looking to see which elements have been added 590or removed. Due to the complicated debug information format, it is very 591difficult to use a regular diff tool to find those elements; even 592impossible when dealing with different debug formats. 593 594:program:`llvm-debuginfo-analyzer` supports a logical element comparison, 595allowing to find semantic differences between logical views, produced by 596different toolchain versions or even debug information formats. 597 598When comparing logical views created from different debug formats, its 599accuracy depends on how close the debug information represents the 600user code. For instance, a logical view created from a binary file with 601DWARF debug information may include more detailed data than a logical 602view created from a binary file with CodeView debug information. 603 604The following options describe the elements to compare. 605 606.. option:: --compare=<value[,value,...]> 607 608 With **value** being one of the options in the following list. 609 610 .. code-block:: text 611 612 =all: Include all the below elements. 613 614 .. code-block:: text 615 616 =lines: Include lines. 617 =scopes: Include scopes. 618 =symbols: Include symbols. 619 =types: Include types. 620 621:program:`llvm-debuginfo-analyzer` takes the first binary file on the 622command line as the **reference** and the second one as the **target**. 623To get a more descriptive report, the comparison is done twice. The 624reference and target views are swapped, in order to produce those 625**missing** elements from the target view and those **added** elements 626to the reference view. 627 628See :option:`--report` options on how to describe the comparison 629reports. 630 631.. _warning_: 632 633WARNING 634~~~~~~~ 635When reading the input object files, :program:`llvm-debuginfo-analyzer` 636can detect issues in the raw debug information. These may not be 637considered fatal to the purpose of printing a logical view but they can 638give an indication about the quality and potentially expose issues with 639the generated debug information. 640 641The following options describe the warnings to be recorded for later 642printing, if they are requested by :option:`--print`. 643 644.. option:: --warning=<value[,value,...]> 645 646 With **value** being one of the options in the following list. 647 648 .. code-block:: text 649 650 =all: Include all the below warnings. 651 652 The following options collect additional information during the creation 653 of the logical view, to include invalid coverage values and locations 654 for symbols; invalid code ranges; lines that are zero. 655 656 .. code-block:: text 657 658 =coverages: Invalid symbol coverages values. 659 =lines: Debug lines that are zero. 660 =locations: Invalid symbol locations. 661 =ranges: Invalid code ranges. 662 663.. _internal_: 664 665INTERNAL 666~~~~~~~~ 667 For a better understanding of the logical view, access to more detailed 668 internal information could be needed. Such data would help to identify 669 debug information processed or incorrect logical element management. 670 Typically these kind of options are available only in *debug* builds. 671 672 :program:`llvm-debuginfo-analyzer` supports these advanced options in 673 both *release* and *debug* builds, with the exception of the unique ID 674 that is generated only in *debug* builds. 675 676.. option:: --internal=<value[,value,...]> 677 678 With **value** being one of the options in the following list. 679 680 .. code-block:: text 681 682 =all: Include all the below options. 683 684 The following options allow to check the integrity of the logical view; 685 collect the debug tags that are processed or not implemented; ignore the 686 logical element line number, to facilitate the logical view comparison 687 when using external comparison tools; print the command line options 688 used to invoke :program:`llvm-debuginfo-analyzer`. 689 690 .. code-block:: text 691 692 =id: Print unique element ID. 693 =cmdline: Print command line. 694 =integrity: Check elements integrity. 695 =none: Ignore element line number. 696 =tag: Debug information tags. 697 698 **Note:** For ELF format, the collected tags represent the debug tags 699 that are not processed. For PE/COFF format, they represent the tags 700 that are processed. 701 702EXAMPLES 703-------- 704This section includes some real binary files to show how to use 705:program:`llvm-debuginfo-analyzer` to print a logical view and to 706diagnose possible debug information issues. 707 708TEST CASE 1 - GENERAL OPTIONS 709~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 710The below example is used to show different output generated by 711:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86 712ELF target with Clang (-O0 -g): 713 714.. code-block:: c++ 715 716 1 using INTPTR = const int *; 717 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { 718 3 if (ParamBool) { 719 4 typedef int INTEGER; 720 5 const INTEGER CONSTANT = 7; 721 6 return CONSTANT; 722 7 } 723 8 return ParamUnsigned; 724 9 } 725 726PRINTING MODE 727^^^^^^^^^^^^^ 728In this mode :program:`llvm-debuginfo-analyzer` prints the *logical view* 729or portions of it, based on criteria patterns (including regular 730expressions) to select the kind of *logical elements* to be included in 731the output. 732 733BASIC DETAILS 734""""""""""""" 735The following command prints basic details for all the logical elements 736sorted by the debug information internal offset; it includes its lexical 737level and debug info format. 738 739.. code-block:: none 740 741 llvm-debuginfo-analyzer --attribute=level,format 742 --output-sort=offset 743 --print=scopes,symbols,types,lines,instructions 744 test-dwarf-clang.o 745 746or 747 748.. code-block:: none 749 750 llvm-debuginfo-analyzer --attribute=level,format 751 --output-sort=offset 752 --print=elements 753 test-dwarf-clang.o 754 755Each row represents an element that is present within the debug 756information. The first column represents the scope level, followed by 757the associated line number (if any), and finally the description of 758the element. 759 760.. code-block:: none 761 762 Logical View: 763 [000] {File} 'test-dwarf-clang.o' -> elf64-x86-64 764 765 [001] {CompileUnit} 'test.cpp' 766 [002] 2 {Function} extern not_inlined 'foo' -> 'int' 767 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' 768 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' 769 [003] 2 {Parameter} 'ParamBool' -> 'bool' 770 [003] {Block} 771 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 772 [004] 5 {Line} 773 [004] {Code} 'movl $0x7, -0x1c(%rbp)' 774 [004] 6 {Line} 775 [004] {Code} 'movl $0x7, -0x4(%rbp)' 776 [004] {Code} 'jmp 0x6' 777 [004] 8 {Line} 778 [004] {Code} 'movl -0x14(%rbp), %eax' 779 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 780 [003] 2 {Line} 781 [003] {Code} 'pushq %rbp' 782 [003] {Code} 'movq %rsp, %rbp' 783 [003] {Code} 'movb %dl, %al' 784 [003] {Code} 'movq %rdi, -0x10(%rbp)' 785 [003] {Code} 'movl %esi, -0x14(%rbp)' 786 [003] {Code} 'andb $0x1, %al' 787 [003] {Code} 'movb %al, -0x15(%rbp)' 788 [003] 3 {Line} 789 [003] {Code} 'testb $0x1, -0x15(%rbp)' 790 [003] {Code} 'je 0x13' 791 [003] 8 {Line} 792 [003] {Code} 'movl %eax, -0x4(%rbp)' 793 [003] 9 {Line} 794 [003] {Code} 'movl -0x4(%rbp), %eax' 795 [003] {Code} 'popq %rbp' 796 [003] {Code} 'retq' 797 [003] 9 {Line} 798 [002] 1 {TypeAlias} 'INTPTR' -> '* const int' 799 800On closer inspection, we can see what could be a potential debug issue: 801 802.. code-block:: none 803 804 [003] {Block} 805 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 806 807The **'INTEGER'** definition is at level **[003]**, the same lexical 808scope as the anonymous **{Block}** ('true' branch for the 'if' statement) 809whereas in the original source code the typedef statement is clearly 810inside that block, so the **'INTEGER'** definition should also be at 811level **[004]** inside the block. 812 813SELECT LOGICAL ELEMENTS 814""""""""""""""""""""""" 815The following prints all *instructions*, *symbols* and *types* that 816contain **'inte'** or **'movl'** in their names or types, using a tab 817layout and given the number of matches. 818 819.. code-block:: none 820 821 llvm-debuginfo-analyzer --attribute=level 822 --select-nocase --select-regex 823 --select=INTe --select=movl 824 --report=list 825 --print=symbols,types,instructions,summary 826 test-dwarf-clang.o 827 828 Logical View: 829 [000] {File} 'test-dwarf-clang.o' 830 831 [001] {CompileUnit} 'test.cpp' 832 [003] {Code} 'movl $0x7, -0x1c(%rbp)' 833 [003] {Code} 'movl $0x7, -0x4(%rbp)' 834 [003] {Code} 'movl %eax, -0x4(%rbp)' 835 [003] {Code} 'movl %esi, -0x14(%rbp)' 836 [003] {Code} 'movl -0x14(%rbp), %eax' 837 [003] {Code} 'movl -0x4(%rbp), %eax' 838 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 839 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 840 841 ----------------------------- 842 Element Total Found 843 ----------------------------- 844 Scopes 3 0 845 Symbols 4 1 846 Types 2 1 847 Lines 17 6 848 ----------------------------- 849 Total 26 8 850 851COMPARISON MODE 852^^^^^^^^^^^^^^^ 853In this mode :program:`llvm-debuginfo-analyzer` compares logical views 854to produce a report with the logical elements that are missing or added. 855This a very powerful aid in finding semantic differences in the debug 856information produced by different toolchain versions or even completely 857different toolchains altogether (For example a compiler producing DWARF 858can be directly compared against a completely different compiler that 859produces CodeView). 860 861Given the previous example we found the above debug information issue 862(related to the previous invalid scope location for the **'typedef int 863INTEGER'**) by comparing against another compiler. 864 865Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern 866with the printing mode to obtain the following logical view output. 867 868.. code-block:: none 869 870 llvm-debuginfo-analyzer --attribute=level 871 --select-regex --select-nocase --select=INTe 872 --report=list 873 --print=symbols,types 874 test-dwarf-clang.o test-dwarf-gcc.o 875 876 Logical View: 877 [000] {File} 'test-dwarf-clang.o' 878 879 [001] {CompileUnit} 'test.cpp' 880 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 881 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 882 883 Logical View: 884 [000] {File} 'test-dwarf-gcc.o' 885 886 [001] {CompileUnit} 'test.cpp' 887 [004] 4 {TypeAlias} 'INTEGER' -> 'int' 888 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 889 890The output shows that both objects contain the same elements. But the 891**'typedef INTEGER'** is located at different scope level. The GCC 892generated object, shows **'4'**, which is the correct value. 893 894Note that there is no requirement that GCC must produce identical or 895similar DWARF to Clang to allow the comparison. We're only comparing 896the semantics. The same case when comparing CodeView debug information 897generated by MSVC and Clang. 898 899There are 2 comparison methods: logical view and logical elements. 900 901LOGICAL VIEW 902"""""""""""" 903It compares the logical view as a whole unit; for a match, each compared 904logical element must have the same parents and children. 905 906Using the :program:`llvm-debuginfo-analyzer` comparison functionality, 907that issue can be seen in a more global context, that can include the 908logical view. 909 910The output shows in view form the **missing (-), added (+)** elements, 911giving more context by swapping the reference and target object files. 912 913.. code-block:: none 914 915 llvm-debuginfo-analyzer --attribute=level 916 --compare=types 917 --report=view 918 --print=symbols,types 919 test-dwarf-clang.o test-dwarf-gcc.o 920 921 Reference: 'test-dwarf-clang.o' 922 Target: 'test-dwarf-gcc.o' 923 924 Logical View: 925 [000] {File} 'test-dwarf-clang.o' 926 927 [001] {CompileUnit} 'test.cpp' 928 [002] 1 {TypeAlias} 'INTPTR' -> '* const int' 929 [002] 2 {Function} extern not_inlined 'foo' -> 'int' 930 [003] {Block} 931 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 932 +[004] 4 {TypeAlias} 'INTEGER' -> 'int' 933 [003] 2 {Parameter} 'ParamBool' -> 'bool' 934 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' 935 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' 936 -[003] 4 {TypeAlias} 'INTEGER' -> 'int' 937 938The output shows the merging view path (reference and target) with the 939missing and added elements. 940 941LOGICAL ELEMENTS 942"""""""""""""""" 943It compares individual logical elements without considering if their 944parents are the same. For both comparison methods, the equal criteria 945includes the name, source code location, type, lexical scope level. 946 947.. code-block:: none 948 949 llvm-debuginfo-analyzer --attribute=level 950 --compare=types 951 --report=list 952 --print=symbols,types,summary 953 test-dwarf-clang.o test-dwarf-gcc.o 954 955 Reference: 'test-dwarf-clang.o' 956 Target: 'test-dwarf-gcc.o' 957 958 (1) Missing Types: 959 -[003] 4 {TypeAlias} 'INTEGER' -> 'int' 960 961 (1) Added Types: 962 +[004] 4 {TypeAlias} 'INTEGER' -> 'int' 963 964 ---------------------------------------- 965 Element Expected Missing Added 966 ---------------------------------------- 967 Scopes 4 0 0 968 Symbols 0 0 0 969 Types 2 1 1 970 Lines 0 0 0 971 ---------------------------------------- 972 Total 6 1 1 973 974Changing the *Reference* and *Target* order: 975 976.. code-block:: none 977 978 llvm-debuginfo-analyzer --attribute=level 979 --compare=types 980 --report=list 981 --print=symbols,types,summary 982 test-dwarf-gcc.o test-dwarf-clang.o 983 984 Reference: 'test-dwarf-gcc.o' 985 Target: 'test-dwarf-clang.o' 986 987 (1) Missing Types: 988 -[004] 4 {TypeAlias} 'INTEGER' -> 'int' 989 990 (1) Added Types: 991 +[003] 4 {TypeAlias} 'INTEGER' -> 'int' 992 993 ---------------------------------------- 994 Element Expected Missing Added 995 ---------------------------------------- 996 Scopes 4 0 0 997 Symbols 0 0 0 998 Types 2 1 1 999 Lines 0 0 0 1000 ---------------------------------------- 1001 Total 6 1 1 1002 1003As the *Reference* and *Target* are switched, the *Added Types* from 1004the first case now are listed as *Missing Types*. 1005 1006TEST CASE 2 - ASSEMBLER INSTRUCTIONS 1007~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1008The below example is used to show different output generated by 1009:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86 1010Codeview and ELF targets with recent versions of Clang, GCC and MSVC 1011(-O0 -g) for Windows and Linux. 1012 1013.. code-block:: c++ 1014 1015 1 extern int printf(const char * format, ... ); 1016 2 1017 3 int main() 1018 4 { 1019 5 printf("Hello, World\n"); 1020 6 return 0; 1021 7 } 1022 1023These are the logical views that :program:`llvm-debuginfo-analyzer` 1024generates for 3 different compilers (MSVC, Clang and GCC), emitting 1025different debug information formats (CodeView, DWARF) on Windows and 1026Linux. 1027 1028.. code-block:: none 1029 1030 llvm-debuginfo-analyzer --attribute=level,format,producer 1031 --print=lines,instructions 1032 hello-world-codeview-clang.o 1033 hello-world-codeview-msvc.o 1034 hello-world-dwarf-clang.o 1035 hello-world-dwarf-gcc.o 1036 1037CodeView - Clang (Windows) 1038^^^^^^^^^^^^^^^^^^^^^^^^^^ 1039 1040.. code-block:: none 1041 1042 Logical View: 1043 [000] {File} 'hello-world-codeview-clang.o' -> COFF-x86-64 1044 1045 [001] {CompileUnit} 'hello-world.cpp' 1046 [002] {Producer} 'clang version 14.0.0' 1047 [002] {Function} extern not_inlined 'main' -> 'int' 1048 [003] 4 {Line} 1049 [003] {Code} 'subq $0x28, %rsp' 1050 [003] {Code} 'movl $0x0, 0x24(%rsp)' 1051 [003] 5 {Line} 1052 [003] {Code} 'leaq (%rip), %rcx' 1053 [003] {Code} 'callq 0x0' 1054 [003] 6 {Line} 1055 [003] {Code} 'xorl %eax, %eax' 1056 [003] {Code} 'addq $0x28, %rsp' 1057 [003] {Code} 'retq' 1058 1059CodeView - MSVC (Windows) 1060^^^^^^^^^^^^^^^^^^^^^^^^^ 1061 1062.. code-block:: none 1063 1064 Logical View: 1065 [000] {File} 'hello-world-codeview-msvc.o' -> COFF-i386 1066 1067 [001] {CompileUnit} 'hello-world.cpp' 1068 [002] {Producer} 'Microsoft (R) Optimizing Compiler' 1069 [002] {Function} extern not_inlined 'main' -> 'int' 1070 [003] 4 {Line} 1071 [003] {Code} 'pushl %ebp' 1072 [003] {Code} 'movl %esp, %ebp' 1073 [003] 5 {Line} 1074 [003] {Code} 'pushl $0x0' 1075 [003] {Code} 'calll 0x0' 1076 [003] {Code} 'addl $0x4, %esp' 1077 [003] 6 {Line} 1078 [003] {Code} 'xorl %eax, %eax' 1079 [003] 7 {Line} 1080 [003] {Code} 'popl %ebp' 1081 [003] {Code} 'retl' 1082 1083DWARF - Clang (Linux) 1084^^^^^^^^^^^^^^^^^^^^^ 1085 1086.. code-block:: none 1087 1088 Logical View: 1089 [000] {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64 1090 1091 [001] {CompileUnit} 'hello-world.cpp' 1092 [002] {Producer} 'clang version 14.0.0' 1093 [002] 3 {Function} extern not_inlined 'main' -> 'int' 1094 [003] 4 {Line} 1095 [003] {Code} 'pushq %rbp' 1096 [003] {Code} 'movq %rsp, %rbp' 1097 [003] {Code} 'subq $0x10, %rsp' 1098 [003] {Code} 'movl $0x0, -0x4(%rbp)' 1099 [003] 5 {Line} 1100 [003] {Code} 'movabsq $0x0, %rdi' 1101 [003] {Code} 'movb $0x0, %al' 1102 [003] {Code} 'callq 0x0' 1103 [003] 6 {Line} 1104 [003] {Code} 'xorl %eax, %eax' 1105 [003] {Code} 'addq $0x10, %rsp' 1106 [003] {Code} 'popq %rbp' 1107 [003] {Code} 'retq' 1108 [003] 6 {Line} 1109 1110DWARF - GCC (Linux) 1111^^^^^^^^^^^^^^^^^^^ 1112 1113.. code-block:: none 1114 1115 Logical View: 1116 [000] {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64 1117 1118 [001] {CompileUnit} 'hello-world.cpp' 1119 [002] {Producer} 'GNU C++14 9.3.0' 1120 [002] 3 {Function} extern not_inlined 'main' -> 'int' 1121 [003] 4 {Line} 1122 [003] {Code} 'endbr64' 1123 [003] {Code} 'pushq %rbp' 1124 [003] {Code} 'movq %rsp, %rbp' 1125 [003] 5 {Line} 1126 [003] {Code} 'leaq (%rip), %rdi' 1127 [003] {Code} 'movl $0x0, %eax' 1128 [003] {Code} 'callq 0x0' 1129 [003] 6 {Line} 1130 [003] {Code} 'movl $0x0, %eax' 1131 [003] 7 {Line} 1132 [003] {Code} 'popq %rbp' 1133 [003] {Code} 'retq' 1134 [003] 7 {Line} 1135 1136The logical views shows the intermixed lines and assembler instructions, 1137allowing to compare the code generated by the different toolchains. 1138 1139TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF 1140~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1141The below example is used to show different output generated by 1142:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86 1143Codeview and ELF targets with recent versions of Clang, GCC and MSVC 1144(-O0 -g). 1145 1146.. code-block:: c++ 1147 1148 1 int bar(float Input) { return (int)Input; } 1149 2 1150 3 unsigned foo(char Param) { 1151 4 typedef int INT; // ** Definition for INT ** 1152 5 INT Value = Param; 1153 6 { 1154 7 typedef float FLOAT; // ** Definition for FLOAT ** 1155 8 { 1156 9 FLOAT Added = Value + Param; 1157 10 Value = bar(Added); 1158 11 } 1159 12 } 1160 13 return Value + Param; 1161 14 } 1162 1163The above test is used to illustrate a scope issue found in the Clang 1164compiler: 1165`PR44884 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=44884>`_ / 1166`PR44229 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/44229>`_ 1167 1168The lines 4 and 7 contains 2 typedefs, defined at different lexical 1169scopes. 1170 1171.. code-block:: c++ 1172 1173 4 typedef int INT; 1174 7 typedef float FLOAT; 1175 1176These are the logical views that :program:`llvm-debuginfo-analyzer` 1177generates for 3 different compilers (MSVC, Clang and GCC), emitting 1178different debug information formats (CodeView, DWARF) on different 1179platforms. 1180 1181.. code-block:: none 1182 1183 llvm-debuginfo-analyzer --attribute=level,format,producer 1184 --print=symbols,types,lines 1185 --output-sort=kind 1186 pr-44884-codeview-clang.o 1187 pr-44884-codeview-msvc.o 1188 pr-44884-dwarf-clang.o 1189 pr-44884-dwarf-gcc.o 1190 1191CodeView - Clang (Windows) 1192^^^^^^^^^^^^^^^^^^^^^^^^^^ 1193 1194.. code-block:: none 1195 1196 Logical View: 1197 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64 1198 1199 [001] {CompileUnit} 'pr-44884.cpp' 1200 [002] {Producer} 'clang version 14.0.0' 1201 [002] {Function} extern not_inlined 'bar' -> 'int' 1202 [003] {Parameter} 'Input' -> 'float' 1203 [003] 1 {Line} 1204 [002] {Function} extern not_inlined 'foo' -> 'unsigned' 1205 [003] {Block} 1206 [004] {Variable} 'Added' -> 'float' 1207 [004] 9 {Line} 1208 [004] 10 {Line} 1209 [003] {Parameter} 'Param' -> 'char' 1210 [003] {TypeAlias} 'FLOAT' -> 'float' 1211 [003] {TypeAlias} 'INT' -> 'int' 1212 [003] {Variable} 'Value' -> 'int' 1213 [003] 3 {Line} 1214 [003] 5 {Line} 1215 [003] 13 {Line} 1216 1217CodeView - MSVC (Windows) 1218^^^^^^^^^^^^^^^^^^^^^^^^^ 1219 1220.. code-block:: none 1221 1222 Logical View: 1223 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i386 1224 1225 [001] {CompileUnit} 'pr-44884.cpp' 1226 [002] {Producer} 'Microsoft (R) Optimizing Compiler' 1227 [002] {Function} extern not_inlined 'bar' -> 'int' 1228 [003] {Variable} 'Input' -> 'float' 1229 [003] 1 {Line} 1230 [002] {Function} extern not_inlined 'foo' -> 'unsigned' 1231 [003] {Block} 1232 [004] {Block} 1233 [005] {Variable} 'Added' -> 'float' 1234 [004] {TypeAlias} 'FLOAT' -> 'float' 1235 [004] 9 {Line} 1236 [004] 10 {Line} 1237 [003] {TypeAlias} 'INT' -> 'int' 1238 [003] {Variable} 'Param' -> 'char' 1239 [003] {Variable} 'Value' -> 'int' 1240 [003] 3 {Line} 1241 [003] 5 {Line} 1242 [003] 13 {Line} 1243 [003] 14 {Line} 1244 1245DWARF - Clang (Linux) 1246^^^^^^^^^^^^^^^^^^^^^ 1247 1248.. code-block:: none 1249 1250 Logical View: 1251 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64 1252 1253 [001] {CompileUnit} 'pr-44884.cpp' 1254 [002] {Producer} 'clang version 14.0.0' 1255 [002] 1 {Function} extern not_inlined 'bar' -> 'int' 1256 [003] 1 {Parameter} 'Input' -> 'float' 1257 [003] 1 {Line} 1258 [003] 1 {Line} 1259 [003] 1 {Line} 1260 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int' 1261 [003] {Block} 1262 [004] 9 {Variable} 'Added' -> 'FLOAT' 1263 [004] 9 {Line} 1264 [004] 9 {Line} 1265 [004] 9 {Line} 1266 [004] 9 {Line} 1267 [004] 9 {Line} 1268 [004] 10 {Line} 1269 [004] 10 {Line} 1270 [004] 10 {Line} 1271 [004] 13 {Line} 1272 [003] 3 {Parameter} 'Param' -> 'char' 1273 [003] 7 {TypeAlias} 'FLOAT' -> 'float' 1274 [003] 4 {TypeAlias} 'INT' -> 'int' 1275 [003] 5 {Variable} 'Value' -> 'INT' 1276 [003] 3 {Line} 1277 [003] 5 {Line} 1278 [003] 5 {Line} 1279 [003] 13 {Line} 1280 [003] 13 {Line} 1281 [003] 13 {Line} 1282 [003] 13 {Line} 1283 1284DWARF - GCC (Linux) 1285^^^^^^^^^^^^^^^^^^^ 1286 1287.. code-block:: none 1288 1289 Logical View: 1290 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm 1291 1292 [001] {CompileUnit} 'pr-44884.cpp' 1293 [002] {Producer} 'GNU C++14 10.2.1 20201103' 1294 [002] 1 {Function} extern not_inlined 'bar' -> 'int' 1295 [003] 1 {Parameter} 'Input' -> 'float' 1296 [003] 1 {Line} 1297 [003] 1 {Line} 1298 [003] 1 {Line} 1299 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int' 1300 [003] {Block} 1301 [004] {Block} 1302 [005] 9 {Variable} 'Added' -> 'FLOAT' 1303 [005] 9 {Line} 1304 [005] 9 {Line} 1305 [005] 9 {Line} 1306 [005] 10 {Line} 1307 [005] 13 {Line} 1308 [004] 7 {TypeAlias} 'FLOAT' -> 'float' 1309 [003] 3 {Parameter} 'Param' -> 'char' 1310 [003] 4 {TypeAlias} 'INT' -> 'int' 1311 [003] 5 {Variable} 'Value' -> 'INT' 1312 [003] 3 {Line} 1313 [003] 5 {Line} 1314 [003] 13 {Line} 1315 [003] 14 {Line} 1316 [003] 14 {Line} 1317 1318From the previous logical views, we can see that the Clang compiler 1319emits **both typedefs at the same lexical scope (3)**, which is wrong. 1320GCC and MSVC emit correct lexical scope for both typedefs. 1321 1322Using the :program:`llvm-debuginfo-analyzer` selection facilities, we 1323can produce a simple tabular output showing just the logical types that 1324are **Typedef**. 1325 1326.. code-block:: none 1327 1328 llvm-debuginfo-analyzer --attribute=level,format 1329 --output-sort=name 1330 --select-types=Typedef 1331 --report=list 1332 --print=types 1333 pr-44884-*.o 1334 1335 Logical View: 1336 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64 1337 1338 [001] {CompileUnit} 'pr_44884.cpp' 1339 [003] {TypeAlias} 'FLOAT' -> 'float' 1340 [003] {TypeAlias} 'INT' -> 'int' 1341 1342 Logical View: 1343 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i386 1344 1345 [001] {CompileUnit} 'pr_44884.cpp' 1346 [004] {TypeAlias} 'FLOAT' -> 'float' 1347 [003] {TypeAlias} 'INT' -> 'int' 1348 1349 Logical View: 1350 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64 1351 1352 [001] {CompileUnit} 'pr_44884.cpp' 1353 [003] 7 {TypeAlias} 'FLOAT' -> 'float' 1354 [003] 4 {TypeAlias} 'INT' -> 'int' 1355 1356 Logical View: 1357 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm 1358 1359 [001] {CompileUnit} 'pr_44884.cpp' 1360 [004] 7 {TypeAlias} 'FLOAT' -> 'float' 1361 [003] 4 {TypeAlias} 'INT' -> 'int' 1362 1363It also shows, that the CodeView debug information does not generate 1364source code line numbers for the those logical types. The logical view 1365is sorted by the types name. 1366 1367TEST CASE 4 - MISSING NESTED ENUMERATIONS 1368~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1369The below example is used to show different output generated by 1370:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86 1371Codeview and ELF targets with recent versions of Clang, GCC and MSVC 1372(-O0 -g). 1373 1374.. code-block:: c++ 1375 1376 1 struct Struct { 1377 2 union Union { 1378 3 enum NestedEnum { RED, BLUE }; 1379 4 }; 1380 5 Union U; 1381 6 }; 1382 7 1383 8 Struct S; 1384 9 int test() { 1385 10 return S.U.BLUE; 1386 11 } 1387 1388The above test is used to illustrate a scope issue found in the Clang 1389compiler: 1390`PR46466 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=46466>`_ / 1391`PR45811 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/45811>`_ 1392 1393These are the logical views that :program:`llvm-debuginfo-analyzer` 1394generates for 3 different compilers (MSVC, Clang and GCC), emitting 1395different debug information formats (CodeView, DWARF) on different 1396platforms. 1397 1398.. code-block:: none 1399 1400 llvm-debuginfo-analyzer --attribute=level,format,producer 1401 --output-sort=name 1402 --print=symbols,types 1403 pr-46466-codeview-clang.o 1404 pr-46466-codeview-msvc.o 1405 pr-46466-dwarf-clang.o 1406 pr-46466-dwarf-gcc.o 1407 1408CodeView - Clang (Windows) 1409^^^^^^^^^^^^^^^^^^^^^^^^^^ 1410 1411.. code-block:: none 1412 1413 Logical View: 1414 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64 1415 1416 [001] {CompileUnit} 'pr-46466.cpp' 1417 [002] {Producer} 'clang version 14.0.0' 1418 [002] {Variable} extern 'S' -> 'Struct' 1419 [002] 1 {Struct} 'Struct' 1420 [003] {Member} public 'U' -> 'Union' 1421 [003] 2 {Union} 'Union' 1422 [004] 3 {Enumeration} 'NestedEnum' -> 'int' 1423 [005] {Enumerator} 'BLUE' = '0x1' 1424 [005] {Enumerator} 'RED' = '0x0' 1425 1426CodeView - MSVC (Windows) 1427^^^^^^^^^^^^^^^^^^^^^^^^^ 1428 1429.. code-block:: none 1430 1431 Logical View: 1432 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386 1433 1434 [001] {CompileUnit} 'pr-46466.cpp' 1435 [002] {Producer} 'Microsoft (R) Optimizing Compiler' 1436 [002] {Variable} extern 'S' -> 'Struct' 1437 [002] 1 {Struct} 'Struct' 1438 [003] {Member} public 'U' -> 'Union' 1439 [003] 2 {Union} 'Union' 1440 [004] 3 {Enumeration} 'NestedEnum' -> 'int' 1441 [005] {Enumerator} 'BLUE' = '0x1' 1442 [005] {Enumerator} 'RED' = '0x0' 1443 1444DWARF - Clang (Linux) 1445^^^^^^^^^^^^^^^^^^^^^ 1446 1447.. code-block:: none 1448 1449 Logical View: 1450 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64 1451 1452 [001] {CompileUnit} 'pr-46466.cpp' 1453 [002] {Producer} 'clang version 14.0.0' 1454 [002] 8 {Variable} extern 'S' -> 'Struct' 1455 [002] 1 {Struct} 'Struct' 1456 [003] 5 {Member} public 'U' -> 'Union' 1457 1458DWARF - GCC (Linux) 1459^^^^^^^^^^^^^^^^^^^ 1460 1461.. code-block:: none 1462 1463 Logical View: 1464 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 1465 1466 [001] {CompileUnit} 'pr-46466.cpp' 1467 [002] {Producer} 'GNU C++14 9.3.0' 1468 [002] 8 {Variable} extern 'S' -> 'Struct' 1469 [002] 1 {Struct} 'Struct' 1470 [003] 5 {Member} public 'U' -> 'Union' 1471 [003] 2 {Union} 'Union' 1472 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int' 1473 [005] {Enumerator} 'BLUE' = '0x1' 1474 [005] {Enumerator} 'RED' = '0x0' 1475 1476From the previous logical views, we can see that the DWARF debug 1477information generated by the Clang compiler does not include any 1478references to the enumerators **RED** and **BLUE**. The DWARF 1479generated by GCC, CodeView generated by Clang and MSVC, they do 1480include such references. 1481 1482Using the :program:`llvm-debuginfo-analyzer` selection facilities, we 1483can produce a logical view showing just the logical types that are 1484**Enumerator** and its parents. The logical view is sorted by the types 1485name. 1486 1487.. code-block:: none 1488 1489 llvm-debuginfo-analyzer --attribute=format,level 1490 --output-sort=name 1491 --select-types=Enumerator 1492 --report=parents 1493 --print=types 1494 pr-46466-*.o 1495 1496.. code-block:: none 1497 1498 Logical View: 1499 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64 1500 1501 [001] {CompileUnit} 'pr-46466.cpp' 1502 [002] 1 {Struct} 'Struct' 1503 [003] 2 {Union} 'Union' 1504 [004] 3 {Enumeration} 'NestedEnum' -> 'int' 1505 [005] {Enumerator} 'BLUE' = '0x1' 1506 [005] {Enumerator} 'RED' = '0x0' 1507 1508 Logical View: 1509 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386 1510 1511 [001] {CompileUnit} 'pr-46466.cpp' 1512 [002] 1 {Struct} 'Struct' 1513 [003] 2 {Union} 'Union' 1514 [004] 3 {Enumeration} 'NestedEnum' -> 'int' 1515 [005] {Enumerator} 'BLUE' = '0x1' 1516 [005] {Enumerator} 'RED' = '0x0' 1517 1518 Logical View: 1519 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64 1520 1521 [001] {CompileUnit} 'pr-46466.cpp' 1522 1523 Logical View: 1524 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 1525 1526 [001] {CompileUnit} 'pr-46466.cpp' 1527 [002] 1 {Struct} 'Struct' 1528 [003] 2 {Union} 'Union' 1529 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int' 1530 [005] {Enumerator} 'BLUE' = '0x1' 1531 [005] {Enumerator} 'RED' = '0x0' 1532 1533Using the :program:`llvm-debuginfo-analyzer` selection facilities, we 1534can produce a simple tabular output including a summary for the logical 1535types that are **Enumerator**. The logical view is sorted by the types 1536name. 1537 1538.. code-block:: none 1539 1540 llvm-debuginfo-analyzer --attribute=format,level 1541 --output-sort=name 1542 --select-types=Enumerator 1543 --print=types,summary 1544 pr-46466-*.o 1545 1546.. code-block:: none 1547 1548 Logical View: 1549 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64 1550 1551 [001] {CompileUnit} 'pr-46466.cpp' 1552 [005] {Enumerator} 'BLUE' = '0x1' 1553 [005] {Enumerator} 'RED' = '0x0' 1554 1555 ----------------------------- 1556 Element Total Found 1557 ----------------------------- 1558 Scopes 5 0 1559 Symbols 2 0 1560 Types 6 2 1561 Lines 0 0 1562 ----------------------------- 1563 Total 13 2 1564 1565 Logical View: 1566 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386 1567 1568 [001] {CompileUnit} 'pr-46466.cpp' 1569 [005] {Enumerator} 'BLUE' = '0x1' 1570 [005] {Enumerator} 'RED' = '0x0' 1571 1572 ----------------------------- 1573 Element Total Found 1574 ----------------------------- 1575 Scopes 5 0 1576 Symbols 2 0 1577 Types 7 2 1578 Lines 0 0 1579 ----------------------------- 1580 Total 14 2 1581 1582 Logical View: 1583 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64 1584 1585 [001] {CompileUnit} 'pr-46466.cpp' 1586 1587 ----------------------------- 1588 Element Total Found 1589 ----------------------------- 1590 Scopes 4 0 1591 Symbols 0 0 1592 Types 0 0 1593 Lines 0 0 1594 ----------------------------- 1595 Total 4 0 1596 1597 Logical View: 1598 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 1599 1600 [001] {CompileUnit} 'pr-46466.cpp' 1601 [005] {Enumerator} 'BLUE' = '0x1' 1602 [005] {Enumerator} 'RED' = '0x0' 1603 1604 ----------------------------- 1605 Element Total Found 1606 ----------------------------- 1607 Scopes 5 0 1608 Symbols 0 0 1609 Types 2 2 1610 Lines 0 0 1611 ----------------------------- 1612 Total 7 2 1613 1614From the values printed under the **Found** column, we can see that no 1615**Types** were found in the DWARF debug information generated by Clang. 1616 1617TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE 1618~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1619The below example is used to show different output generated by 1620:program:`llvm-debuginfo-analyzer`. We compiled the example for an X86 1621Codeview and ELF targets with recent versions of Clang, GCC and MSVC 1622(-O0 -g). 1623 1624.. code-block:: c++ 1625 1626 // definitions.h 1627 #ifdef _MSC_VER 1628 #define forceinline __forceinline 1629 #elif defined(__clang__) 1630 #if __has_attribute(__always_inline__) 1631 #define forceinline inline __attribute__((__always_inline__)) 1632 #else 1633 #define forceinline inline 1634 #endif 1635 #elif defined(__GNUC__) 1636 #define forceinline inline __attribute__((__always_inline__)) 1637 #else 1638 #define forceinline inline 1639 #error 1640 #endif 1641 1642As the test is dependent on inline compiler options, the above header 1643file defines *forceinline*. 1644 1645.. code-block:: c++ 1646 1647 #include "definitions.h" 1648 1649.. code-block:: c++ 1650 1651 1 #include "definitions.h" 1652 2 forceinline int InlineFunction(int Param) { 1653 3 int Var_1 = Param; 1654 4 { 1655 5 int Var_2 = Param + Var_1; 1656 6 Var_1 = Var_2; 1657 7 } 1658 8 return Var_1; 1659 9 } 1660 10 1661 11 int test(int Param_1, int Param_2) { 1662 12 int A = Param_1; 1663 13 A += InlineFunction(Param_2); 1664 14 return A; 1665 15 } 1666 1667The above test is used to illustrate a variable issue found in the Clang 1668compiler: 1669`PR43860 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=43860>`_ / 1670`PR43205 (GitHub) <https://github.com/llvm/llvm-project/issues/43205>`_ 1671 1672These are the logical views that :program:`llvm-debuginfo-analyzer` 1673generates for 3 different compilers (MSVC, Clang and GCC), emitting 1674different debug information formats (CodeView, DWARF) on different 1675platforms. 1676 1677.. code-block:: none 1678 1679 llvm-debuginfo-analyzer --attribute=level,format,producer 1680 --output-sort=name 1681 --print=symbols 1682 pr-43860-codeview-clang.o 1683 pr-43860-codeview-msvc.o 1684 pr-43860-dwarf-clang.o 1685 pr-43860-dwarf-gcc.o 1686 1687CODEVIEW - Clang (Windows) 1688^^^^^^^^^^^^^^^^^^^^^^^^^^ 1689 1690.. code-block:: none 1691 1692 Logical View: 1693 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64 1694 1695 [001] {CompileUnit} 'pr-43860.cpp' 1696 [002] {Producer} 'clang version 14.0.0' 1697 [002] 2 {Function} inlined 'InlineFunction' -> 'int' 1698 [003] {Parameter} '' -> 'int' 1699 [002] {Function} extern not_inlined 'test' -> 'int' 1700 [003] {Variable} 'A' -> 'int' 1701 [003] {InlinedFunction} inlined 'InlineFunction' -> 'int' 1702 [004] {Parameter} 'Param' -> 'int' 1703 [004] {Variable} 'Var_1' -> 'int' 1704 [004] {Variable} 'Var_2' -> 'int' 1705 [003] {Parameter} 'Param_1' -> 'int' 1706 [003] {Parameter} 'Param_2' -> 'int' 1707 1708CODEVIEW - MSVC (Windows) 1709^^^^^^^^^^^^^^^^^^^^^^^^^ 1710 1711.. code-block:: none 1712 1713 Logical View: 1714 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i386 1715 1716 [001] {CompileUnit} 'pr-43860.cpp' 1717 [002] {Producer} 'Microsoft (R) Optimizing Compiler' 1718 [002] {Function} extern not_inlined 'InlineFunction' -> 'int' 1719 [003] {Block} 1720 [004] {Variable} 'Var_2' -> 'int' 1721 [003] {Variable} 'Param' -> 'int' 1722 [003] {Variable} 'Var_1' -> 'int' 1723 [002] {Function} extern not_inlined 'test' -> 'int' 1724 [003] {Variable} 'A' -> 'int' 1725 [003] {Variable} 'Param_1' -> 'int' 1726 [003] {Variable} 'Param_2' -> 'int' 1727 1728DWARF - Clang (Linux) 1729^^^^^^^^^^^^^^^^^^^^^ 1730 1731.. code-block:: none 1732 1733 Logical View: 1734 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64 1735 1736 [001] {CompileUnit} 'pr-43860.cpp' 1737 [002] {Producer} 'clang version 14.0.0' 1738 [002] 2 {Function} extern inlined 'InlineFunction' -> 'int' 1739 [003] {Block} 1740 [004] 5 {Variable} 'Var_2' -> 'int' 1741 [003] 2 {Parameter} 'Param' -> 'int' 1742 [003] 3 {Variable} 'Var_1' -> 'int' 1743 [002] 11 {Function} extern not_inlined 'test' -> 'int' 1744 [003] 12 {Variable} 'A' -> 'int' 1745 [003] 13 {InlinedFunction} inlined 'InlineFunction' -> 'int' 1746 [004] {Block} 1747 [005] {Variable} 'Var_2' -> 'int' 1748 [004] {Parameter} 'Param' -> 'int' 1749 [004] {Variable} 'Var_1' -> 'int' 1750 [003] 11 {Parameter} 'Param_1' -> 'int' 1751 [003] 11 {Parameter} 'Param_2' -> 'int' 1752 1753DWARF - GCC (Linux) 1754^^^^^^^^^^^^^^^^^^^ 1755 1756.. code-block:: none 1757 1758 Logical View: 1759 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64 1760 1761 [001] {CompileUnit} 'pr-43860.cpp' 1762 [002] {Producer} 'GNU C++14 9.3.0' 1763 [002] 2 {Function} extern declared_inlined 'InlineFunction' -> 'int' 1764 [003] {Block} 1765 [004] 5 {Variable} 'Var_2' -> 'int' 1766 [003] 2 {Parameter} 'Param' -> 'int' 1767 [003] 3 {Variable} 'Var_1' -> 'int' 1768 [002] 11 {Function} extern not_inlined 'test' -> 'int' 1769 [003] 12 {Variable} 'A' -> 'int' 1770 [003] 13 {InlinedFunction} declared_inlined 'InlineFunction' -> 'int' 1771 [004] {Block} 1772 [005] {Variable} 'Var_2' -> 'int' 1773 [004] {Parameter} 'Param' -> 'int' 1774 [004] {Variable} 'Var_1' -> 'int' 1775 [003] 11 {Parameter} 'Param_1' -> 'int' 1776 [003] 11 {Parameter} 'Param_2' -> 'int' 1777 1778From the previous logical views, we can see that the CodeView debug 1779information generated by the Clang compiler shows the variables **Var_1** 1780and **Var_2** are at the same lexical scope (**4**) in the function 1781**InlineFuction**. The DWARF generated by GCC/Clang and CodeView 1782generated by MSVC, show those variables at the correct lexical scope: 1783**3** and **4** respectively. 1784 1785Using the :program:`llvm-debuginfo-analyzer` selection facilities, we 1786can produce a simple tabular output showing just the logical elements 1787that have in their name the *var* pattern. The logical view is sorted 1788by the variables name. 1789 1790.. code-block:: none 1791 1792 llvm-debuginfo-analyzer --attribute=level,format 1793 --output-sort=name 1794 --select-regex --select-nocase --select=Var 1795 --report=list 1796 --print=symbols 1797 pr-43860-*.o 1798 1799.. code-block:: none 1800 1801 Logical View: 1802 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64 1803 1804 [001] {CompileUnit} 'pr-43860.cpp' 1805 [004] {Variable} 'Var_1' -> 'int' 1806 [004] {Variable} 'Var_2' -> 'int' 1807 1808 Logical View: 1809 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i386 1810 1811 [001] {CompileUnit} 'pr-43860.cpp' 1812 [003] {Variable} 'Var_1' -> 'int' 1813 [004] {Variable} 'Var_2' -> 'int' 1814 1815 Logical View: 1816 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64 1817 1818 [001] {CompileUnit} 'pr-43860.cpp' 1819 [004] {Variable} 'Var_1' -> 'int' 1820 [003] 3 {Variable} 'Var_1' -> 'int' 1821 [005] {Variable} 'Var_2' -> 'int' 1822 [004] 5 {Variable} 'Var_2' -> 'int' 1823 1824 Logical View: 1825 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64 1826 1827 [001] {CompileUnit} 'pr-43860.cpp' 1828 [004] {Variable} 'Var_1' -> 'int' 1829 [003] 3 {Variable} 'Var_1' -> 'int' 1830 [005] {Variable} 'Var_2' -> 'int' 1831 [004] 5 {Variable} 'Var_2' -> 'int' 1832 1833It also shows, that the CodeView debug information does not generate 1834source code line numbers for the those logical symbols. The logical 1835view is sorted by the types name. 1836 1837TEST CASE 6 - FULL LOGICAL VIEW 1838~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1839For advanced users, :program:`llvm-debuginfo-analyzer` can display low 1840level information that includes offsets within the debug information 1841section, debug location operands, linkage names, etc. 1842 1843.. code-block:: none 1844 1845 llvm-debuginfo-analyzer --attribute=all 1846 --print=all 1847 test-dwarf-clang.o 1848 1849 Logical View: 1850 [0x0000000000][000] {File} 'test-dwarf-clang.o' -> elf64-x86-64 1851 1852 [0x000000000b][001] {CompileUnit} 'test.cpp' 1853 [0x000000000b][002] {Producer} 'clang version 12.0.0' 1854 {Directory} '' 1855 {File} 'test.cpp' 1856 {Public} 'foo' [0x0000000000:0x000000003a] 1857 [0x000000000b][002] {Range} Lines 2:9 [0x0000000000:0x000000003a] 1858 [0x00000000bc][002] {BaseType} 'bool' 1859 [0x0000000099][002] {BaseType} 'int' 1860 [0x00000000b5][002] {BaseType} 'unsigned int' 1861 1862 [0x00000000a0][002] {Source} '/test.cpp' 1863 [0x00000000a0][002] 1 {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int' 1864 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int' 1865 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a] 1866 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb' 1867 [0x0000000071][003] {Block} 1868 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f] 1869 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER' 1870 [0x000000007e][005] {Coverage} 100.00% 1871 [0x000000007f][005] {Location} 1872 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg] 1873 [0x000000001c][004] 5 {Line} {NewStatement} '/test.cpp' 1874 [0x000000001c][004] {Code} 'movl $0x7, -0x1c(%rbp)' 1875 [0x0000000023][004] 6 {Line} {NewStatement} '/test.cpp' 1876 [0x0000000023][004] {Code} 'movl $0x7, -0x4(%rbp)' 1877 [0x000000002a][004] {Code} 'jmp 0x6' 1878 [0x000000002f][004] 8 {Line} {NewStatement} '/test.cpp' 1879 [0x000000002f][004] {Code} 'movl -0x14(%rbp), %eax' 1880 [0x0000000063][003] 2 {Parameter} 'ParamBool' -> [0x00000000bc]'bool' 1881 [0x0000000063][004] {Coverage} 100.00% 1882 [0x0000000064][004] {Location} 1883 [0x0000000064][005] {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg] 1884 [0x0000000047][003] 2 {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR' 1885 [0x0000000047][004] {Coverage} 100.00% 1886 [0x0000000048][004] {Location} 1887 [0x0000000048][005] {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg] 1888 [0x0000000055][003] 2 {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int' 1889 [0x0000000055][004] {Coverage} 100.00% 1890 [0x0000000056][004] {Location} 1891 [0x0000000056][005] {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg] 1892 [0x000000008d][003] 4 {TypeAlias} 'INTEGER' -> [0x0000000099]'int' 1893 [0x0000000000][003] 2 {Line} {NewStatement} '/test.cpp' 1894 [0x0000000000][003] {Code} 'pushq %rbp' 1895 [0x0000000001][003] {Code} 'movq %rsp, %rbp' 1896 [0x0000000004][003] {Code} 'movb %dl, %al' 1897 [0x0000000006][003] {Code} 'movq %rdi, -0x10(%rbp)' 1898 [0x000000000a][003] {Code} 'movl %esi, -0x14(%rbp)' 1899 [0x000000000d][003] {Code} 'andb $0x1, %al' 1900 [0x000000000f][003] {Code} 'movb %al, -0x15(%rbp)' 1901 [0x0000000012][003] 3 {Line} {NewStatement} {PrologueEnd} '/test.cpp' 1902 [0x0000000012][003] {Code} 'testb $0x1, -0x15(%rbp)' 1903 [0x0000000016][003] {Code} 'je 0x13' 1904 [0x0000000032][003] 8 {Line} '/test.cpp' 1905 [0x0000000032][003] {Code} 'movl %eax, -0x4(%rbp)' 1906 [0x0000000035][003] 9 {Line} {NewStatement} '/test.cpp' 1907 [0x0000000035][003] {Code} 'movl -0x4(%rbp), %eax' 1908 [0x0000000038][003] {Code} 'popq %rbp' 1909 [0x0000000039][003] {Code} 'retq' 1910 [0x000000003a][003] 9 {Line} {NewStatement} {EndSequence} '/test.cpp' 1911 1912 ----------------------------- 1913 Element Total Printed 1914 ----------------------------- 1915 Scopes 3 3 1916 Symbols 4 4 1917 Types 5 5 1918 Lines 25 25 1919 ----------------------------- 1920 Total 37 37 1921 1922 Scope Sizes: 1923 189 (100.00%) : [0x000000000b][001] {CompileUnit} 'test.cpp' 1924 110 ( 58.20%) : [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int' 1925 27 ( 14.29%) : [0x0000000071][003] {Block} 1926 1927 Totals by lexical level: 1928 [001]: 189 (100.00%) 1929 [002]: 110 ( 58.20%) 1930 [003]: 27 ( 14.29%) 1931 1932The **Scope Sizes** table shows the contribution in bytes to the debug 1933information by each scope, which can be used to determine unexpected 1934size changes in the DWARF sections between different versions of the 1935same toolchain. 1936 1937.. code-block:: none 1938 1939 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int' 1940 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a] 1941 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb' 1942 [0x0000000071][003] {Block} 1943 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f] 1944 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER' 1945 [0x000000007e][005] {Coverage} 100.00% 1946 [0x000000007f][005] {Location} 1947 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg] 1948 1949The **{Range}** attribute describe the line ranges for a logical scope. 1950For this case, the function **foo** is within the lines **2** and **9**. 1951 1952The **{Coverage}** and **{Location}** attributes describe the debug 1953location and coverage for logical symbols. For optimized code, the 1954coverage value decreases and it affects the program debuggability. 1955 1956WEBASSEMBLY SUPPORT 1957~~~~~~~~~~~~~~~~~~~ 1958The below example is used to show the WebAssembly output generated by 1959:program:`llvm-debuginfo-analyzer`. We compiled the example for a 1960WebAssembly 32-bit target with Clang (-O0 -g --target=wasm32): 1961 1962.. code-block:: c++ 1963 1964 1 using INTPTR = const int *; 1965 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { 1966 3 if (ParamBool) { 1967 4 typedef int INTEGER; 1968 5 const INTEGER CONSTANT = 7; 1969 6 return CONSTANT; 1970 7 } 1971 8 return ParamUnsigned; 1972 9 } 1973 1974PRINT BASIC DETAILS 1975^^^^^^^^^^^^^^^^^^^ 1976The following command prints basic details for all the logical elements 1977sorted by the debug information internal offset; it includes its lexical 1978level and debug info format. 1979 1980.. code-block:: none 1981 1982 llvm-debuginfo-analyzer --attribute=level,format 1983 --output-sort=offset 1984 --print=scopes,symbols,types,lines,instructions 1985 test-clang.o 1986 1987or 1988 1989.. code-block:: none 1990 1991 llvm-debuginfo-analyzer --attribute=level,format 1992 --output-sort=offset 1993 --print=elements 1994 test-clang.o 1995 1996Each row represents an element that is present within the debug 1997information. The first column represents the scope level, followed by 1998the associated line number (if any), and finally the description of 1999the element. 2000 2001.. code-block:: none 2002 2003 Logical View: 2004 [000] {File} 'test-clang.o' -> WASM 2005 2006 [001] {CompileUnit} 'test.cpp' 2007 [002] 2 {Function} extern not_inlined 'foo' -> 'int' 2008 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' 2009 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' 2010 [003] 2 {Parameter} 'ParamBool' -> 'bool' 2011 [003] {Block} 2012 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 2013 [004] 5 {Line} 2014 [004] {Code} 'i32.const 7' 2015 [004] {Code} 'local.set 10' 2016 [004] {Code} 'local.get 5' 2017 [004] {Code} 'local.get 10' 2018 [004] {Code} 'i32.store 12' 2019 [004] 6 {Line} 2020 [004] {Code} 'i32.const 7' 2021 [004] {Code} 'local.set 11' 2022 [004] {Code} 'local.get 5' 2023 [004] {Code} 'local.get 11' 2024 [004] {Code} 'i32.store 28' 2025 [004] {Code} 'br 1' 2026 [004] - {Line} 2027 [004] {Code} 'end' 2028 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 2029 [003] 2 {Line} 2030 [003] {Code} 'nop' 2031 [003] {Code} 'end' 2032 [003] {Code} 'i64.div_s' 2033 [003] {Code} 'global.get 0' 2034 [003] {Code} 'local.set 3' 2035 [003] {Code} 'i32.const 32' 2036 [003] {Code} 'local.set 4' 2037 [003] {Code} 'local.get 3' 2038 [003] {Code} 'local.get 4' 2039 [003] {Code} 'i32.sub' 2040 [003] {Code} 'local.set 5' 2041 [003] {Code} 'local.get 5' 2042 [003] {Code} 'local.get 0' 2043 [003] {Code} 'i32.store 24' 2044 [003] {Code} 'local.get 5' 2045 [003] {Code} 'local.get 1' 2046 [003] {Code} 'i32.store 20' 2047 [003] {Code} 'local.get 2' 2048 [003] {Code} 'local.set 6' 2049 [003] {Code} 'local.get 5' 2050 [003] {Code} 'local.get 6' 2051 [003] {Code} 'i32.store8 19' 2052 [003] 3 {Line} 2053 [003] {Code} 'local.get 5' 2054 [003] {Code} 'i32.load8_u 19' 2055 [003] {Code} 'local.set 7' 2056 [003] 3 {Line} 2057 [003] {Code} 'i32.const 1' 2058 [003] {Code} 'local.set 8' 2059 [003] {Code} 'local.get 7' 2060 [003] {Code} 'local.get 8' 2061 [003] {Code} 'i32.and' 2062 [003] {Code} 'local.set 9' 2063 [003] {Code} 'block' 2064 [003] {Code} 'block' 2065 [003] {Code} 'local.get 9' 2066 [003] {Code} 'i32.eqz' 2067 [003] {Code} 'br_if 0' 2068 [003] 8 {Line} 2069 [003] {Code} 'local.get 5' 2070 [003] {Code} 'i32.load 20' 2071 [003] {Code} 'local.set 12' 2072 [003] 8 {Line} 2073 [003] {Code} 'local.get 5' 2074 [003] {Code} 'local.get 12' 2075 [003] {Code} 'i32.store 28' 2076 [003] - {Line} 2077 [003] {Code} 'end' 2078 [003] 9 {Line} 2079 [003] {Code} 'local.get 5' 2080 [003] {Code} 'i32.load 28' 2081 [003] {Code} 'local.set 13' 2082 [003] {Code} 'local.get 13' 2083 [003] {Code} 'return' 2084 [003] {Code} 'end' 2085 [003] 9 {Line} 2086 [003] {Code} 'unreachable' 2087 [002] 1 {TypeAlias} 'INTPTR' -> '* const int' 2088 2089SELECT LOGICAL ELEMENTS 2090^^^^^^^^^^^^^^^^^^^^^^^ 2091The following prints all *instructions*, *symbols* and *types* that 2092contain **'block'** or **'.store'** in their names or types, using a tab 2093layout and given the number of matches. 2094 2095.. code-block:: none 2096 2097 llvm-debuginfo-analyzer --attribute=level 2098 --select-nocase --select-regex 2099 --select=BLOCK --select=.store 2100 --report=list 2101 --print=symbols,types,instructions,summary 2102 test-clang.o 2103 2104 Logical View: 2105 [000] {File} 'test-clang.o' 2106 2107 [001] {CompileUnit} 'test.cpp' 2108 [003] {Code} 'block' 2109 [003] {Code} 'block' 2110 [004] {Code} 'i32.store 12' 2111 [003] {Code} 'i32.store 20' 2112 [003] {Code} 'i32.store 24' 2113 [004] {Code} 'i32.store 28' 2114 [003] {Code} 'i32.store 28' 2115 [003] {Code} 'i32.store8 19' 2116 2117 ----------------------------- 2118 Element Total Printed 2119 ----------------------------- 2120 Scopes 3 0 2121 Symbols 4 0 2122 Types 2 0 2123 Lines 62 8 2124 ----------------------------- 2125 Total 71 8 2126 2127COMPARISON MODE 2128^^^^^^^^^^^^^^^ 2129Given the previous example we found the above debug information issue 2130(related to the previous invalid scope location for the **'typedef int 2131INTEGER'**) by comparing against another compiler. 2132 2133Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern 2134with the printing mode to obtain the following logical view output. 2135 2136.. code-block:: none 2137 2138 llvm-debuginfo-analyzer --attribute=level 2139 --select-regex --select-nocase --select=INTe 2140 --report=list 2141 --print=symbols,types 2142 test-clang.o test-dwarf-gcc.o 2143 2144 Logical View: 2145 [000] {File} 'test-clang.o' 2146 2147 [001] {CompileUnit} 'test.cpp' 2148 [003] 4 {TypeAlias} 'INTEGER' -> 'int' 2149 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 2150 2151 Logical View: 2152 [000] {File} 'test-dwarf-gcc.o' 2153 2154 [001] {CompileUnit} 'test.cpp' 2155 [004] 4 {TypeAlias} 'INTEGER' -> 'int' 2156 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 2157 2158The output shows that both objects contain the same elements. But the 2159**'typedef INTEGER'** is located at different scope level. The GCC 2160generated object, shows **'4'**, which is the correct value. 2161 2162There are 2 comparison methods: logical view and logical elements. 2163 2164LOGICAL VIEW 2165"""""""""""" 2166It compares the logical view as a whole unit; for a match, each compared 2167logical element must have the same parents and children. 2168 2169The output shows in view form the **missing (-), added (+)** elements, 2170giving more context by swapping the reference and target object files. 2171 2172.. code-block:: none 2173 2174 llvm-debuginfo-analyzer --attribute=level 2175 --compare=types 2176 --report=view 2177 --print=symbols,types 2178 test-clang.o test-dwarf-gcc.o 2179 2180 Reference: 'test-clang.o' 2181 Target: 'test-dwarf-gcc.o' 2182 2183 Logical View: 2184 [000] {File} 'test-clang.o' 2185 2186 [001] {CompileUnit} 'test.cpp' 2187 [002] 1 {TypeAlias} 'INTPTR' -> '* const int' 2188 [002] 2 {Function} extern not_inlined 'foo' -> 'int' 2189 [003] {Block} 2190 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' 2191 +[004] 4 {TypeAlias} 'INTEGER' -> 'int' 2192 [003] 2 {Parameter} 'ParamBool' -> 'bool' 2193 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' 2194 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' 2195 -[003] 4 {TypeAlias} 'INTEGER' -> 'int' 2196 2197The output shows the merging view path (reference and target) with the 2198missing and added elements. 2199 2200LOGICAL ELEMENTS 2201"""""""""""""""" 2202It compares individual logical elements without considering if their 2203parents are the same. For both comparison methods, the equal criteria 2204includes the name, source code location, type, lexical scope level. 2205 2206.. code-block:: none 2207 2208 llvm-debuginfo-analyzer --attribute=level 2209 --compare=types 2210 --report=list 2211 --print=symbols,types,summary 2212 test-clang.o test-dwarf-gcc.o 2213 2214 Reference: 'test-clang.o' 2215 Target: 'test-dwarf-gcc.o' 2216 2217 (1) Missing Types: 2218 -[003] 4 {TypeAlias} 'INTEGER' -> 'int' 2219 2220 (1) Added Types: 2221 +[004] 4 {TypeAlias} 'INTEGER' -> 'int' 2222 2223 ---------------------------------------- 2224 Element Expected Missing Added 2225 ---------------------------------------- 2226 Scopes 4 0 0 2227 Symbols 0 0 0 2228 Types 2 1 1 2229 Lines 0 0 0 2230 ---------------------------------------- 2231 Total 6 1 1 2232 2233Changing the *Reference* and *Target* order: 2234 2235.. code-block:: none 2236 2237 llvm-debuginfo-analyzer --attribute=level 2238 --compare=types 2239 --report=list 2240 --print=symbols,types,summary 2241 test-dwarf-gcc.o test-clang.o 2242 2243 Reference: 'test-dwarf-gcc.o' 2244 Target: 'test-clang.o' 2245 2246 (1) Missing Types: 2247 -[004] 4 {TypeAlias} 'INTEGER' -> 'int' 2248 2249 (1) Added Types: 2250 +[003] 4 {TypeAlias} 'INTEGER' -> 'int' 2251 2252 ---------------------------------------- 2253 Element Expected Missing Added 2254 ---------------------------------------- 2255 Scopes 4 0 0 2256 Symbols 0 0 0 2257 Types 2 1 1 2258 Lines 0 0 0 2259 ---------------------------------------- 2260 Total 6 1 1 2261 2262As the *Reference* and *Target* are switched, the *Added Types* from 2263the first case now are listed as *Missing Types*. 2264 2265EXIT STATUS 2266----------- 2267:program:`llvm-debuginfo-analyzer` returns 0 if the input files were 2268parsed and printed successfully. Otherwise, it returns 1. 2269 2270LIMITATIONS AND KNOWN ISSUES 2271---------------------------- 2272See :download:`Limitations <../../tools/llvm-debuginfo-analyzer/README.md>`. 2273 2274SEE ALSO 2275-------- 2276:manpage:`llvm-dwarfdump` 2277