1 llvm-debuginfo-analyzer - Print a logical representation of low-level debug information.
2 ========================================================================================
4 .. program:: llvm-debuginfo-analyzer
11 :program:`llvm-debuginfo-analyzer` [*options*] [*filename ...*]
15 :program:`llvm-debuginfo-analyzer` parses debug and text sections in
16 binary object files and prints their contents in a logical view, which
17 is a human readable representation that closely matches the structure
18 of the original user source code. Supported object file formats include
19 ELF, Mach-O, PDB and COFF.
21 The **logical view** abstracts the complexity associated with the
22 different low-level representations of the debugging information that
23 is embedded in the object file. :program:`llvm-debuginfo-analyzer`
24 produces a canonical view of the debug information regardless of how it
25 is formatted. The same logical view will be seen regardless of object
26 file format, assuming the debug information correctly represents the
27 same original source code.
29 The logical view includes the following **logical elements**: *type*,
30 *scope*, *symbol* and *line*, which are the basic software elements used
31 in 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
34 attributes to include when printing a logical element. A logical element
35 may have a **kind** that describes specific types of elements. For
36 instance, a *scope* could have a kind value of *function*, *class*,
39 :program:`llvm-debuginfo-analyzer` defaults to print a pre-defined
40 layout of logical elements and attributes. The command line options can
41 be used to control the printed elements (:option:`--print`), using a
42 specific layout (:option:`--report`), matching a given pattern
43 (:option:`--select`, :option:`--select-offsets`). Also, the output can
44 be limited to specified logical elements using (:option:`--select-lines`,
45 :option:`--select-scopes`, :option:`--select-symbols`,
46 :option:`--select-types`).
48 :program:`llvm-debuginfo-analyzer` can also compare a set of logical
49 views (:option:`--compare`), to find differences and identify possible
50 debug information syntax issues (:option:`--warning`) in any object file.
54 :program:`llvm-debuginfo-analyzer` options are separated into several
55 categories, each tailored to a different purpose:
57 * :ref:`general_` - Standard LLVM options to display help, version, etc.
58 * :ref:`attributes_` - Describe how to include different details when
60 * :ref:`print_` - Specify which elements will be included when printing
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
68 * :ref:`warning_` - Print the warnings detected during the creation
70 * :ref:`internal_` - Internal analysis of the logical view.
76 This section describes the standard help options, used to display the
77 usage, version, response files, etc.
79 .. option:: -h, --help
81 Show help and usage for this command. (--help-hidden for more).
83 .. option:: --help-list
85 Show help and usage for this command without grouping the options
86 into categories (--help-list-hidden for more).
88 .. option:: --help-hidden
90 Display all available options.
92 .. option:: --print-all-options
94 Print all option values after command line parsing.
96 .. option:: --print-options
98 Print non-default options after command line parsing
100 .. option:: --version
102 Display the version of the tool.
106 Read command-line options from `<FILE>`.
108 If no input file is specified, :program:`llvm-debuginfo-analyzer`
109 defaults to read `a.out` and return an error when no input file is found.
111 If `-` is used as the input file, :program:`llvm-debuginfo-analyzer`
112 reads the input from its standard input stream.
118 The following options enable attributes given for the printed elements.
119 The attributes are divided in categories based on the type of data being
120 added, such as: internal offsets in the binary file, location descriptors,
121 register names, user source filenames, additional element transformations,
122 toolchain name, binary file format, etc.
124 .. option:: --attribute=<value[,value,...]>
126 With **value** being one of the options in the following lists.
130 =all: Include all the below attributes.
131 =extended: Add low-level attributes.
132 =standard: Add standard high-level attributes.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
209 The following attribute described specific information for the **PE/COFF**
210 file format. It includes MS runtime types.
214 =system: Display PDB's MS system elements.
216 The above attributes are grouped into *standard* and *extended*
217 categories that can be enabled.
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.
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.
269 The following options describe the elements to print. The layout used
270 is determined by the :option:`--report`. In the tree layout, all the
271 elements have their enclosing lexical scopes printed, even when not
272 explicitly specified.
274 .. option:: --print=<value[,value,...]>
276 With **value** being one of the options in the following lists.
280 =all: Include all the below attributes.
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
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).
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.
304 =sizes: Debug Information scopes contributions.
305 =summary: Summary of elements allocated, selected or printed.
306 =warnings: Warnings detected.
308 Note: The **--print=sizes** option is ELF specific.
314 The following options describe how to control the output generated when
315 printing the logical elements.
317 .. option:: --output-file=<path>
319 Redirect the output to a file specified by <path>, where - is the
320 standard output stream.
322 :program:`llvm-debuginfo-analyzer` has the concept of **split view**.
323 When redirecting the output from a complex binary format, it is
324 **divided** into individual files, each one containing the logical view
325 output for a single compilation unit.
327 .. option:: --output-folder=<name>
329 The folder to write a file per compilation unit when **--output=split**
332 .. option:: --output-level=<level>
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
338 .. option:: --output=<value[,value,...]>
340 With **value** being one of the options in the following lists.
344 =all: Include all the below outputs.
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.
352 .. option:: --output-sort=<key>
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.
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.
372 Depending on the task being executed (print, compare, select), several
373 layouts are supported to display the elements in a more suitable way,
374 to make the output easier to understand.
376 .. option:: --report=<value[,value,...]>
378 With **value** being one of the options in the following list.
382 =all: Include all the below reports.
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.
391 The **list** layout presents the logical elements in a tabular form
392 without any parent-child relationship. This may be the preferred way to
393 display elements that match specific conditions when comparing logical
394 views, making it easier to find differences.
396 The **children**, **parents** and **view** layout displays the elements
397 in a tree format, with the scopes representing their nodes, and types,
398 symbols, lines and other scopes representing the children. The layout
399 shows the lexical scoping relationship between elements, with the binary
400 file being the tree root (level 0) and each compilation unit being a
403 The **children** layout includes the elements that match any given
404 criteria (:option:`--select`) or (:option:`--compare`) and its children.
406 The **parents** layout includes the elements that match any given
407 criteria (:option:`--select`) or (:option:`--compare`) and its parents.
409 The combined **view** layout includes the elements that match any given
410 criteria (:option:`--select`) or (:option:`--compare`), its parents
415 1. When a selection criteria (:option:`--select`) is specified with no
416 report option, the **list** layout is selected.
417 2. The comparison mode always uses the **view** layout.
423 When printing an element, different data can be included and it varies
424 (:option:`--attribute`) from data directly associated with the binary
425 file (offset) to high level details such as coverage, lexical scope
426 level, location. As the printed output can reach a considerable size,
427 several selection options, enable printing of specific elements.
429 The pattern matching can ignore the case (:option:`--select-nocase`)
430 and be extended to use regular expressions (:option:`--select-regex`).
434 The following options allow printing of elements that match the given
435 <pattern>, offset <value> or an element <condition>.
437 .. option:: --select=<pattern>
439 Print all elements whose name or line number matches the given <pattern>.
441 .. option:: --select-offsets=<value[,value,...]>
443 Print all elements whose offset matches the given values. See
444 :option:`--attribute` option.
446 .. option:: --select-elements=<condition[,condition,...]>
448 Print all elements that satisfy the given <condition>. With **condition**
449 being one of the options in the following list.
453 =discarded: Discarded elements by the linker.
454 =global: Element referenced across Compile Units.
455 =optimized: Optimized inlined abstract references.
457 .. option:: --select-nocase
459 Pattern matching is case-insensitive when using :option:`--select`.
461 .. option:: --select-regex
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.
467 If the <pattern> criteria is too general, a more selective option can
468 be specified to target a particular category of elements:
469 lines (:option:`--select-lines`), scopes (:option:`--select-scopes`),
470 symbols (:option:`--select-symbols`) and types (:option:`--select-types`).
471 These options require knowledge of the debug information format (DWARF,
472 CodeView, COFF), as the given **kind** describes a very specific type
477 The following options allow printing of lines that match the given <kind>.
478 The given criteria describes the debug line state machine registers.
480 .. option:: --select-lines=<kind[,kind,...]>
482 With **kind** being one of the options in the following list.
486 =AlwaysStepInto: marks an always step into.
487 =BasicBlock: Marks a new basic block.
488 =Discriminator: Line that has a discriminator.
489 =EndSequence: Marks the end in the sequence of lines.
490 =EpilogueBegin: Marks the start of a function epilogue.
491 =LineDebug: Lines that correspond to debug lines.
492 =LineAssembler: Lines that correspond to disassembly text.
493 =NeverStepInto: marks a never step into.
494 =NewStatement: Marks a new statement.
495 =PrologueEnd: Marks the end of a function prologue.
499 The following options allow printing of scopes that match the given <kind>.
501 .. option:: --select-scopes=<kind[,kind,...]>
503 With **kind** being one of the options in the following list.
507 =Aggregate: A class, structure or union.
509 =Block: A generic block (lexical block or exception block).
510 =CallSite: A call site.
511 =CatchBlock: An exception block.
513 =CompileUnit: A compile unit.
514 =EntryPoint: A subroutine entry point.
515 =Enumeration: An enumeration.
516 =Function: A function.
517 =FunctionType: A function pointer.
518 =InlinedFunction: An inlined function.
520 =LexicalBlock: A lexical block.
521 =Namespace: A namespace.
522 =Root: The element representing the main scope.
523 =Structure: A structure.
524 =Subprogram: A subprogram.
525 =Template: A template definition.
526 =TemplateAlias: A template alias.
527 =TemplatePack: A template pack.
528 =TryBlock: An exception try block.
533 The following options allow printing of symbols that match the given <kind>.
535 .. option:: --select-symbols=<kind[,kind,...]>
537 With **kind** being one of the options in the following list.
541 =CallSiteParameter: A call site parameter.
542 =Constant: A constant symbol.
543 =Inheritance: A base class.
544 =Member: A member class.
545 =Parameter: A parameter to function.
546 =Unspecified: Unspecified parameters to function.
547 =Variable: A variable.
551 The following options allow printing of types that match the given <kind>.
553 .. option:: --select-types=<kind[,kind,...]>
555 With **kind** being one of the options in the following list.
559 =Base: Base type (integer, boolean, etc).
560 =Const: Constant specifier.
561 =Enumerator: Enumerator.
562 =Import: Import declaration.
563 =ImportDeclaration: Import declaration.
564 =ImportModule: Import module.
565 =Pointer: Pointer type.
566 =PointerMember: Pointer to member function.
567 =Reference: Reference type.
568 =Restrict: Restrict specifier.
569 =RvalueReference: R-value reference.
570 =Subrange: Array subrange.
571 =TemplateParam: Template parameter.
572 =TemplateTemplateParam: Template template parameter.
573 =TemplateTypeParam: Template type parameter.
574 =TemplateValueParam: Template value parameter.
575 =Typedef: Type definition.
576 =Unspecified: Unspecified type.
577 =Volatile: Volatile specifier.
583 When dealing with debug information, there are situations when the
584 printing of the elements is not the correct approach. That is the case,
585 when we are interested in the effects caused by different versions of
586 the same toolchain, or the impact of specific compiler optimizations.
588 For those cases, we are looking to see which elements have been added
589 or removed. Due to the complicated debug information format, it is very
590 difficult to use a regular diff tool to find those elements; even
591 impossible when dealing with different debug formats.
593 :program:`llvm-debuginfo-analyzer` supports a logical element comparison,
594 allowing to find semantic differences between logical views, produced by
595 different toolchain versions or even debug information formats.
597 When comparing logical views created from different debug formats, its
598 accuracy depends on how close the debug information represents the
599 user code. For instance, a logical view created from a binary file with
600 DWARF debug information may include more detailed data than a logical
601 view created from a binary file with CodeView/COFF debug information.
603 The following options describe the elements to compare.
605 .. option:: --compare=<value[,value,...]>
607 With **value** being one of the options in the following list.
611 =all: Include all the below elements.
615 =lines: Include lines.
616 =scopes: Include scopes.
617 =symbols: Include symbols.
618 =types: Include types.
620 :program:`llvm-debuginfo-analyzer` takes the first binary file on the
621 command line as the **reference** and the second one as the **target**.
622 To get a more descriptive report, the comparison is done twice. The
623 reference and target views are swapped, in order to produce those
624 **missing** elements from the target view and those **added** elements
625 to the reference view.
627 See :option:`--report` options on how to describe the comparison
634 When reading the input object files, :program:`llvm-debuginfo-analyzer`
635 can detect issues in the raw debug information. These may not be
636 considered fatal to the purpose of printing a logical view but they can
637 give an indication about the quality and potentially expose issues with
638 the generated debug information.
640 The following options describe the warnings to be recorded for later
641 printing, if they are requested by :option:`--print`.
643 .. option:: --warning=<value[,value,...]>
645 With **value** being one of the options in the following list.
649 =all: Include all the below warnings.
651 The following options collect additional information during the creation
652 of the logical view, to include invalid coverage values and locations
653 for symbols; invalid code ranges; lines that are zero.
657 =coverages: Invalid symbol coverages values.
658 =lines: Debug lines that are zero.
659 =locations: Invalid symbol locations.
660 =ranges: Invalid code ranges.
666 For a better understanding of the logical view, access to more detailed
667 internal information could be needed. Such data would help to identify
668 debug information processed or incorrect logical element management.
669 Typically these kind of options are available only in *debug* builds.
671 :program:`llvm-debuginfo-analyzer` supports these advanced options in
672 both *release* and *debug* builds, with the exception of the unique ID
673 that is generated only in *debug* builds.
675 .. option:: --internal=<value[,value,...]>
677 With **value** being one of the options in the following list.
681 =all: Include all the below options.
683 The following options allow to check the integrity of the logical view;
684 collect the debug tags that are processed or not implemented; ignore the
685 logical element line number, to facilitate the logical view comparison
686 when using external comparison tools; print the command line options
687 used to invoke :program:`llvm-debuginfo-analyzer`.
691 =id: Print unique element ID.
692 =cmdline: Print command line.
693 =integrity: Check elements integrity.
694 =none: Ignore element line number.
695 =tag: Debug information tags.
697 **Note:** For ELF format, the collected tags represent the debug tags
698 that are not processed. For PE/COFF format, they represent the tags
703 This section includes some real binary files to show how to use
704 :program:`llvm-debuginfo-analyzer` to print a logical view and to
705 diagnose possible debug information issues.
707 TEST CASE 1 - GENERAL OPTIONS
708 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
709 The below example is used to show different output generated by
710 :program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
711 ELF target with Clang (-O0 -g):
715 1 using INTPTR = const int *;
716 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) {
718 4 typedef int INTEGER;
719 5 const INTEGER CONSTANT = 7;
722 8 return ParamUnsigned;
727 In this mode :program:`llvm-debuginfo-analyzer` prints the *logical view*
728 or portions of it, based on criteria patterns (including regular
729 expressions) to select the kind of *logical elements* to be included in
734 The following command prints basic details for all the logical elements
735 sorted by the debug information internal offset; it includes its lexical
736 level and debug info format.
740 llvm-debuginfo-analyzer --attribute=level,format
742 --print=scopes,symbols,types,lines,instructions
749 llvm-debuginfo-analyzer --attribute=level,format
754 Each row represents an element that is present within the debug
755 information. The first column represents the scope level, followed by
756 the associated line number (if any), and finally the description of
762 [000] {File} 'test-dwarf-clang.o' -> elf64-x86-64
764 [001] {CompileUnit} 'test.cpp'
765 [002] 2 {Function} extern not_inlined 'foo' -> 'int'
766 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
767 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
768 [003] 2 {Parameter} 'ParamBool' -> 'bool'
770 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
772 [004] {Code} 'movl $0x7, -0x1c(%rbp)'
774 [004] {Code} 'movl $0x7, -0x4(%rbp)'
775 [004] {Code} 'jmp 0x6'
777 [004] {Code} 'movl -0x14(%rbp), %eax'
778 [003] 4 {TypeAlias} 'INTEGER' -> 'int'
780 [003] {Code} 'pushq %rbp'
781 [003] {Code} 'movq %rsp, %rbp'
782 [003] {Code} 'movb %dl, %al'
783 [003] {Code} 'movq %rdi, -0x10(%rbp)'
784 [003] {Code} 'movl %esi, -0x14(%rbp)'
785 [003] {Code} 'andb $0x1, %al'
786 [003] {Code} 'movb %al, -0x15(%rbp)'
788 [003] {Code} 'testb $0x1, -0x15(%rbp)'
789 [003] {Code} 'je 0x13'
791 [003] {Code} 'movl %eax, -0x4(%rbp)'
793 [003] {Code} 'movl -0x4(%rbp), %eax'
794 [003] {Code} 'popq %rbp'
797 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
799 On closer inspection, we can see what could be a potential debug issue:
804 [003] 4 {TypeAlias} 'INTEGER' -> 'int'
806 The **'INTEGER'** definition is at level **[003]**, the same lexical
807 scope as the anonymous **{Block}** ('true' branch for the 'if' statement)
808 whereas in the original source code the typedef statement is clearly
809 inside that block, so the **'INTEGER'** definition should also be at
810 level **[004]** inside the block.
812 SELECT LOGICAL ELEMENTS
813 """""""""""""""""""""""
814 The following prints all *instructions*, *symbols* and *types* that
815 contain **'inte'** or **'movl'** in their names or types, using a tab
816 layout and given the number of matches.
820 llvm-debuginfo-analyzer --attribute=level
821 --select-nocase --select-regex
822 --select=INTe --select=movl
824 --print=symbols,types,instructions,summary
828 [000] {File} 'test-dwarf-clang.o'
830 [001] {CompileUnit} 'test.cpp'
831 [003] {Code} 'movl $0x7, -0x1c(%rbp)'
832 [003] {Code} 'movl $0x7, -0x4(%rbp)'
833 [003] {Code} 'movl %eax, -0x4(%rbp)'
834 [003] {Code} 'movl %esi, -0x14(%rbp)'
835 [003] {Code} 'movl -0x14(%rbp), %eax'
836 [003] {Code} 'movl -0x4(%rbp), %eax'
837 [003] 4 {TypeAlias} 'INTEGER' -> 'int'
838 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
840 -----------------------------
842 -----------------------------
847 -----------------------------
852 In this mode :program:`llvm-debuginfo-analyzer` compares logical views
853 to produce a report with the logical elements that are missing or added.
854 This a very powerful aid in finding semantic differences in the debug
855 information produced by different toolchain versions or even completely
856 different toolchains altogether (For example a compiler producing DWARF
857 can be directly compared against a completely different compiler that
860 Given the previous example we found the above debug information issue
861 (related to the previous invalid scope location for the **'typedef int
862 INTEGER'**) by comparing against another compiler.
864 Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern
865 with the printing mode to obtain the following logical view output.
869 llvm-debuginfo-analyzer --attribute=level
870 --select-regex --select-nocase --select=INTe
872 --print=symbols,types
873 test-dwarf-clang.o test-dwarf-gcc.o
876 [000] {File} 'test-dwarf-clang.o'
878 [001] {CompileUnit} 'test.cpp'
879 [003] 4 {TypeAlias} 'INTEGER' -> 'int'
880 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
883 [000] {File} 'test-dwarf-gcc.o'
885 [001] {CompileUnit} 'test.cpp'
886 [004] 4 {TypeAlias} 'INTEGER' -> 'int'
887 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
889 The output shows that both objects contain the same elements. But the
890 **'typedef INTEGER'** is located at different scope level. The GCC
891 generated object, shows **'4'**, which is the correct value.
893 Note that there is no requirement that GCC must produce identical or
894 similar DWARF to Clang to allow the comparison. We're only comparing
895 the semantics. The same case when comparing CodeView debug information
896 generated by MSVC and Clang.
898 There are 2 comparison methods: logical view and logical elements.
902 It compares the logical view as a whole unit; for a match, each compared
903 logical element must have the same parents and children.
905 Using the :program:`llvm-debuginfo-analyzer` comparison functionality,
906 that issue can be seen in a more global context, that can include the
909 The output shows in view form the **missing (-), added (+)** elements,
910 giving more context by swapping the reference and target object files.
914 llvm-debuginfo-analyzer --attribute=level
917 --print=symbols,types
918 test-dwarf-clang.o test-dwarf-gcc.o
920 Reference: 'test-dwarf-clang.o'
921 Target: 'test-dwarf-gcc.o'
924 [000] {File} 'test-dwarf-clang.o'
926 [001] {CompileUnit} 'test.cpp'
927 [002] 1 {TypeAlias} 'INTPTR' -> '* const int'
928 [002] 2 {Function} extern not_inlined 'foo' -> 'int'
930 [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER'
931 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'
932 [003] 2 {Parameter} 'ParamBool' -> 'bool'
933 [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
934 [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int'
935 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'
937 The output shows the merging view path (reference and target) with the
938 missing and added elements.
942 It compares individual logical elements without considering if their
943 parents are the same. For both comparison methods, the equal criteria
944 includes the name, source code location, type, lexical scope level.
948 llvm-debuginfo-analyzer --attribute=level
951 --print=symbols,types,summary
952 test-dwarf-clang.o test-dwarf-gcc.o
954 Reference: 'test-dwarf-clang.o'
955 Target: 'test-dwarf-gcc.o'
958 -[003] 4 {TypeAlias} 'INTEGER' -> 'int'
961 +[004] 4 {TypeAlias} 'INTEGER' -> 'int'
963 ----------------------------------------
964 Element Expected Missing Added
965 ----------------------------------------
970 ----------------------------------------
973 Changing the *Reference* and *Target* order:
977 llvm-debuginfo-analyzer --attribute=level
980 --print=symbols,types,summary
981 test-dwarf-gcc.o test-dwarf-clang.o
983 Reference: 'test-dwarf-gcc.o'
984 Target: 'test-dwarf-clang.o'
987 -[004] 4 {TypeAlias} 'INTEGER' -> 'int'
990 +[003] 4 {TypeAlias} 'INTEGER' -> 'int'
992 ----------------------------------------
993 Element Expected Missing Added
994 ----------------------------------------
999 ----------------------------------------
1002 As the *Reference* and *Target* are switched, the *Added Types* from
1003 the first case now are listed as *Missing Types*.
1005 TEST CASE 2 - ASSEMBLER INSTRUCTIONS
1006 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1007 The below example is used to show different output generated by
1008 :program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1009 Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1010 (-O0 -g) for Windows and Linux.
1014 1 extern int printf(const char * format, ... );
1018 5 printf("Hello, World\n");
1022 These are the logical views that :program:`llvm-debuginfo-analyzer`
1023 generates for 3 different compilers (MSVC, Clang and GCC), emitting
1024 different debug information formats (CodeView, DWARF) on Windows and
1027 .. code-block:: none
1029 llvm-debuginfo-analyzer --attribute=level,format,producer
1030 --print=lines,instructions
1031 hello-world-codeview-clang.o
1032 hello-world-codeview-msvc.o
1033 hello-world-dwarf-clang.o
1034 hello-world-dwarf-gcc.o
1036 CodeView - Clang (Windows)
1037 ^^^^^^^^^^^^^^^^^^^^^^^^^^
1039 .. code-block:: none
1042 [000] {File} 'hello-world-codeview-clang.o' -> COFF-x86-64
1044 [001] {CompileUnit} 'hello-world.cpp'
1045 [002] {Producer} 'clang version 14.0.0'
1046 [002] {Function} extern not_inlined 'main' -> 'int'
1048 [003] {Code} 'subq $0x28, %rsp'
1049 [003] {Code} 'movl $0x0, 0x24(%rsp)'
1051 [003] {Code} 'leaq (%rip), %rcx'
1052 [003] {Code} 'callq 0x0'
1054 [003] {Code} 'xorl %eax, %eax'
1055 [003] {Code} 'addq $0x28, %rsp'
1058 CodeView - MSVC (Windows)
1059 ^^^^^^^^^^^^^^^^^^^^^^^^^
1061 .. code-block:: none
1064 [000] {File} 'hello-world-codeview-msvc.o' -> COFF-i386
1066 [001] {CompileUnit} 'hello-world.cpp'
1067 [002] {Producer} 'Microsoft (R) Optimizing Compiler'
1068 [002] {Function} extern not_inlined 'main' -> 'int'
1070 [003] {Code} 'pushl %ebp'
1071 [003] {Code} 'movl %esp, %ebp'
1073 [003] {Code} 'pushl $0x0'
1074 [003] {Code} 'calll 0x0'
1075 [003] {Code} 'addl $0x4, %esp'
1077 [003] {Code} 'xorl %eax, %eax'
1079 [003] {Code} 'popl %ebp'
1082 DWARF - Clang (Linux)
1083 ^^^^^^^^^^^^^^^^^^^^^
1085 .. code-block:: none
1088 [000] {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64
1090 [001] {CompileUnit} 'hello-world.cpp'
1091 [002] {Producer} 'clang version 14.0.0'
1092 [002] 3 {Function} extern not_inlined 'main' -> 'int'
1094 [003] {Code} 'pushq %rbp'
1095 [003] {Code} 'movq %rsp, %rbp'
1096 [003] {Code} 'subq $0x10, %rsp'
1097 [003] {Code} 'movl $0x0, -0x4(%rbp)'
1099 [003] {Code} 'movabsq $0x0, %rdi'
1100 [003] {Code} 'movb $0x0, %al'
1101 [003] {Code} 'callq 0x0'
1103 [003] {Code} 'xorl %eax, %eax'
1104 [003] {Code} 'addq $0x10, %rsp'
1105 [003] {Code} 'popq %rbp'
1112 .. code-block:: none
1115 [000] {File} 'hello-world-dwarf-gcc.o' -> elf64-x86-64
1117 [001] {CompileUnit} 'hello-world.cpp'
1118 [002] {Producer} 'GNU C++14 9.3.0'
1119 [002] 3 {Function} extern not_inlined 'main' -> 'int'
1121 [003] {Code} 'endbr64'
1122 [003] {Code} 'pushq %rbp'
1123 [003] {Code} 'movq %rsp, %rbp'
1125 [003] {Code} 'leaq (%rip), %rdi'
1126 [003] {Code} 'movl $0x0, %eax'
1127 [003] {Code} 'callq 0x0'
1129 [003] {Code} 'movl $0x0, %eax'
1131 [003] {Code} 'popq %rbp'
1135 The logical views shows the intermixed lines and assembler instructions,
1136 allowing to compare the code generated by the different toolchains.
1138 TEST CASE 3 - INCORRECT LEXICAL SCOPE FOR TYPEDEF
1139 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1140 The below example is used to show different output generated by
1141 :program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1142 Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1147 1 int bar(float Input) { return (int)Input; }
1149 3 unsigned foo(char Param) {
1150 4 typedef int INT; // ** Definition for INT **
1151 5 INT Value = Param;
1153 7 typedef float FLOAT; // ** Definition for FLOAT **
1155 9 FLOAT Added = Value + Param;
1156 10 Value = bar(Added);
1159 13 return Value + Param;
1162 The above test is used to illustrate a scope issue found in the Clang
1164 `PR44884 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=44884>`_ /
1165 `PR44229 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/44229>`_
1167 The lines 4 and 7 contains 2 typedefs, defined at different lexical
1173 7 typedef float FLOAT;
1175 These are the logical views that :program:`llvm-debuginfo-analyzer`
1176 generates for 3 different compilers (MSVC, Clang and GCC), emitting
1177 different debug information formats (CodeView, DWARF) on different
1180 .. code-block:: none
1182 llvm-debuginfo-analyzer --attribute=level,format,producer
1183 --print=symbols,types,lines
1185 pr-44884-codeview-clang.o
1186 pr-44884-codeview-msvc.o
1187 pr-44884-dwarf-clang.o
1188 pr-44884-dwarf-gcc.o
1190 CodeView - Clang (Windows)
1191 ^^^^^^^^^^^^^^^^^^^^^^^^^^
1193 .. code-block:: none
1196 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
1198 [001] {CompileUnit} 'pr-44884.cpp'
1199 [002] {Producer} 'clang version 14.0.0'
1200 [002] {Function} extern not_inlined 'bar' -> 'int'
1201 [003] {Parameter} 'Input' -> 'float'
1203 [002] {Function} extern not_inlined 'foo' -> 'unsigned'
1205 [004] {Variable} 'Added' -> 'float'
1208 [003] {Parameter} 'Param' -> 'char'
1209 [003] {TypeAlias} 'FLOAT' -> 'float'
1210 [003] {TypeAlias} 'INT' -> 'int'
1211 [003] {Variable} 'Value' -> 'int'
1216 CodeView - MSVC (Windows)
1217 ^^^^^^^^^^^^^^^^^^^^^^^^^
1219 .. code-block:: none
1222 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
1224 [001] {CompileUnit} 'pr-44884.cpp'
1225 [002] {Producer} 'Microsoft (R) Optimizing Compiler'
1226 [002] {Function} extern not_inlined 'bar' -> 'int'
1227 [003] {Variable} 'Input' -> 'float'
1229 [002] {Function} extern not_inlined 'foo' -> 'unsigned'
1232 [005] {Variable} 'Added' -> 'float'
1233 [004] {TypeAlias} 'FLOAT' -> 'float'
1236 [003] {TypeAlias} 'INT' -> 'int'
1237 [003] {Variable} 'Param' -> 'char'
1238 [003] {Variable} 'Value' -> 'int'
1244 DWARF - Clang (Linux)
1245 ^^^^^^^^^^^^^^^^^^^^^
1247 .. code-block:: none
1250 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
1252 [001] {CompileUnit} 'pr-44884.cpp'
1253 [002] {Producer} 'clang version 14.0.0'
1254 [002] 1 {Function} extern not_inlined 'bar' -> 'int'
1255 [003] 1 {Parameter} 'Input' -> 'float'
1259 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int'
1261 [004] 9 {Variable} 'Added' -> 'FLOAT'
1271 [003] 3 {Parameter} 'Param' -> 'char'
1272 [003] 7 {TypeAlias} 'FLOAT' -> 'float'
1273 [003] 4 {TypeAlias} 'INT' -> 'int'
1274 [003] 5 {Variable} 'Value' -> 'INT'
1286 .. code-block:: none
1289 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
1291 [001] {CompileUnit} 'pr-44884.cpp'
1292 [002] {Producer} 'GNU C++14 10.2.1 20201103'
1293 [002] 1 {Function} extern not_inlined 'bar' -> 'int'
1294 [003] 1 {Parameter} 'Input' -> 'float'
1298 [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int'
1301 [005] 9 {Variable} 'Added' -> 'FLOAT'
1307 [004] 7 {TypeAlias} 'FLOAT' -> 'float'
1308 [003] 3 {Parameter} 'Param' -> 'char'
1309 [003] 4 {TypeAlias} 'INT' -> 'int'
1310 [003] 5 {Variable} 'Value' -> 'INT'
1317 From the previous logical views, we can see that the Clang compiler
1318 emits **both typedefs at the same lexical scope (3)**, which is wrong.
1319 GCC and MSVC emit correct lexical scope for both typedefs.
1321 Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1322 can produce a simple tabular output showing just the logical types that
1325 .. code-block:: none
1327 llvm-debuginfo-analyzer --attribute=level,format
1329 --select-types=Typedef
1335 [000] {File} 'pr-44884-codeview-clang.o' -> COFF-x86-64
1337 [001] {CompileUnit} 'pr_44884.cpp'
1338 [003] {TypeAlias} 'FLOAT' -> 'float'
1339 [003] {TypeAlias} 'INT' -> 'int'
1342 [000] {File} 'pr-44884-codeview-msvc.o' -> COFF-i386
1344 [001] {CompileUnit} 'pr_44884.cpp'
1345 [004] {TypeAlias} 'FLOAT' -> 'float'
1346 [003] {TypeAlias} 'INT' -> 'int'
1349 [000] {File} 'pr-44884-dwarf-clang.o' -> elf64-x86-64
1351 [001] {CompileUnit} 'pr_44884.cpp'
1352 [003] 7 {TypeAlias} 'FLOAT' -> 'float'
1353 [003] 4 {TypeAlias} 'INT' -> 'int'
1356 [000] {File} 'pr-44884-dwarf-gcc.o' -> elf32-littlearm
1358 [001] {CompileUnit} 'pr_44884.cpp'
1359 [004] 7 {TypeAlias} 'FLOAT' -> 'float'
1360 [003] 4 {TypeAlias} 'INT' -> 'int'
1362 It also shows, that the CodeView debug information does not generate
1363 source code line numbers for the those logical types. The logical view
1364 is sorted by the types name.
1366 TEST CASE 4 - MISSING NESTED ENUMERATIONS
1367 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1368 The below example is used to show different output generated by
1369 :program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1370 Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1377 3 enum NestedEnum { RED, BLUE };
1387 The above test is used to illustrate a scope issue found in the Clang
1389 `PR46466 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=46466>`_ /
1390 `PR45811 (GitHub LLVM) <https://github.com/llvm/llvm-project/issues/45811>`_
1392 These are the logical views that :program:`llvm-debuginfo-analyzer`
1393 generates for 3 different compilers (MSVC, Clang and GCC), emitting
1394 different debug information formats (CodeView, DWARF) on different
1397 .. code-block:: none
1399 llvm-debuginfo-analyzer --attribute=level,format,producer
1401 --print=symbols,types
1402 pr-46466-codeview-clang.o
1403 pr-46466-codeview-msvc.o
1404 pr-46466-dwarf-clang.o
1405 pr-46466-dwarf-gcc.o
1407 CodeView - Clang (Windows)
1408 ^^^^^^^^^^^^^^^^^^^^^^^^^^
1410 .. code-block:: none
1413 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1415 [001] {CompileUnit} 'pr-46466.cpp'
1416 [002] {Producer} 'clang version 14.0.0'
1417 [002] {Variable} extern 'S' -> 'Struct'
1418 [002] 1 {Struct} 'Struct'
1419 [003] {Member} public 'U' -> 'Union'
1420 [003] 2 {Union} 'Union'
1421 [004] 3 {Enumeration} 'NestedEnum' -> 'int'
1422 [005] {Enumerator} 'BLUE' = '0x1'
1423 [005] {Enumerator} 'RED' = '0x0'
1425 CodeView - MSVC (Windows)
1426 ^^^^^^^^^^^^^^^^^^^^^^^^^
1428 .. code-block:: none
1431 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1433 [001] {CompileUnit} 'pr-46466.cpp'
1434 [002] {Producer} 'Microsoft (R) Optimizing Compiler'
1435 [002] {Variable} extern 'S' -> 'Struct'
1436 [002] 1 {Struct} 'Struct'
1437 [003] {Member} public 'U' -> 'Union'
1438 [003] 2 {Union} 'Union'
1439 [004] 3 {Enumeration} 'NestedEnum' -> 'int'
1440 [005] {Enumerator} 'BLUE' = '0x1'
1441 [005] {Enumerator} 'RED' = '0x0'
1443 DWARF - Clang (Linux)
1444 ^^^^^^^^^^^^^^^^^^^^^
1446 .. code-block:: none
1449 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1451 [001] {CompileUnit} 'pr-46466.cpp'
1452 [002] {Producer} 'clang version 14.0.0'
1453 [002] 8 {Variable} extern 'S' -> 'Struct'
1454 [002] 1 {Struct} 'Struct'
1455 [003] 5 {Member} public 'U' -> 'Union'
1460 .. code-block:: none
1463 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1465 [001] {CompileUnit} 'pr-46466.cpp'
1466 [002] {Producer} 'GNU C++14 9.3.0'
1467 [002] 8 {Variable} extern 'S' -> 'Struct'
1468 [002] 1 {Struct} 'Struct'
1469 [003] 5 {Member} public 'U' -> 'Union'
1470 [003] 2 {Union} 'Union'
1471 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
1472 [005] {Enumerator} 'BLUE' = '0x1'
1473 [005] {Enumerator} 'RED' = '0x0'
1475 From the previous logical views, we can see that the DWARF debug
1476 information generated by the Clang compiler does not include any
1477 references to the enumerators **RED** and **BLUE**. The DWARF
1478 generated by GCC, CodeView generated by Clang and MSVC, they do
1479 include such references.
1481 Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1482 can produce a logical view showing just the logical types that are
1483 **Enumerator** and its parents. The logical view is sorted by the types
1486 .. code-block:: none
1488 llvm-debuginfo-analyzer --attribute=format,level
1490 --select-types=Enumerator
1495 .. code-block:: none
1498 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1500 [001] {CompileUnit} 'pr-46466.cpp'
1501 [002] 1 {Struct} 'Struct'
1502 [003] 2 {Union} 'Union'
1503 [004] 3 {Enumeration} 'NestedEnum' -> 'int'
1504 [005] {Enumerator} 'BLUE' = '0x1'
1505 [005] {Enumerator} 'RED' = '0x0'
1508 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1510 [001] {CompileUnit} 'pr-46466.cpp'
1511 [002] 1 {Struct} 'Struct'
1512 [003] 2 {Union} 'Union'
1513 [004] 3 {Enumeration} 'NestedEnum' -> 'int'
1514 [005] {Enumerator} 'BLUE' = '0x1'
1515 [005] {Enumerator} 'RED' = '0x0'
1518 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1520 [001] {CompileUnit} 'pr-46466.cpp'
1523 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1525 [001] {CompileUnit} 'pr-46466.cpp'
1526 [002] 1 {Struct} 'Struct'
1527 [003] 2 {Union} 'Union'
1528 [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
1529 [005] {Enumerator} 'BLUE' = '0x1'
1530 [005] {Enumerator} 'RED' = '0x0'
1532 Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1533 can produce a simple tabular output including a summary for the logical
1534 types that are **Enumerator**. The logical view is sorted by the types
1537 .. code-block:: none
1539 llvm-debuginfo-analyzer --attribute=format,level
1541 --select-types=Enumerator
1542 --print=types,summary
1545 .. code-block:: none
1548 [000] {File} 'pr-46466-codeview-clang.o' -> COFF-x86-64
1550 [001] {CompileUnit} 'pr-46466.cpp'
1551 [005] {Enumerator} 'BLUE' = '0x1'
1552 [005] {Enumerator} 'RED' = '0x0'
1554 -----------------------------
1556 -----------------------------
1561 -----------------------------
1565 [000] {File} 'pr-46466-codeview-msvc.o' -> COFF-i386
1567 [001] {CompileUnit} 'pr-46466.cpp'
1568 [005] {Enumerator} 'BLUE' = '0x1'
1569 [005] {Enumerator} 'RED' = '0x0'
1571 -----------------------------
1573 -----------------------------
1578 -----------------------------
1582 [000] {File} 'pr-46466-dwarf-clang.o' -> elf64-x86-64
1584 [001] {CompileUnit} 'pr-46466.cpp'
1586 -----------------------------
1588 -----------------------------
1593 -----------------------------
1597 [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64
1599 [001] {CompileUnit} 'pr-46466.cpp'
1600 [005] {Enumerator} 'BLUE' = '0x1'
1601 [005] {Enumerator} 'RED' = '0x0'
1603 -----------------------------
1605 -----------------------------
1610 -----------------------------
1613 From the values printed under the **Found** column, we can see that no
1614 **Types** were found in the DWARF debug information generated by Clang.
1616 TEST CASE 5 - INCORRECT LEXICAL SCOPE FOR VARIABLE
1617 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1618 The below example is used to show different output generated by
1619 :program:`llvm-debuginfo-analyzer`. We compiled the example for an X86
1620 Codeview and ELF targets with recent versions of Clang, GCC and MSVC
1627 #define forceinline __forceinline
1628 #elif defined(__clang__)
1629 #if __has_attribute(__always_inline__)
1630 #define forceinline inline __attribute__((__always_inline__))
1632 #define forceinline inline
1634 #elif defined(__GNUC__)
1635 #define forceinline inline __attribute__((__always_inline__))
1637 #define forceinline inline
1641 As the test is dependent on inline compiler options, the above header
1642 file defines *forceinline*.
1646 #include "definitions.h"
1650 1 #include "definitions.h"
1651 2 forceinline int InlineFunction(int Param) {
1652 3 int Var_1 = Param;
1654 5 int Var_2 = Param + Var_1;
1660 11 int test(int Param_1, int Param_2) {
1662 13 A += InlineFunction(Param_2);
1666 The above test is used to illustrate a variable issue found in the Clang
1668 `PR43860 (Bugs LLVM) <https://bugs.llvm.org/show_bug.cgi?id=43860>`_ /
1669 `PR43205 (GitHub) <https://github.com/llvm/llvm-project/issues/43205>`_
1671 These are the logical views that :program:`llvm-debuginfo-analyzer`
1672 generates for 3 different compilers (MSVC, Clang and GCC), emitting
1673 different debug information formats (CodeView, DWARF) on different
1676 .. code-block:: none
1678 llvm-debuginfo-analyzer --attribute=level,format,producer
1681 pr-43860-codeview-clang.o
1682 pr-43860-codeview-msvc.o
1683 pr-43860-dwarf-clang.o
1684 pr-43860-dwarf-gcc.o
1686 CODEVIEW - Clang (Windows)
1687 ^^^^^^^^^^^^^^^^^^^^^^^^^^
1689 .. code-block:: none
1692 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
1694 [001] {CompileUnit} 'pr-43860.cpp'
1695 [002] {Producer} 'clang version 14.0.0'
1696 [002] 2 {Function} inlined 'InlineFunction' -> 'int'
1697 [003] {Parameter} '' -> 'int'
1698 [002] {Function} extern not_inlined 'test' -> 'int'
1699 [003] {Variable} 'A' -> 'int'
1700 [003] {InlinedFunction} inlined 'InlineFunction' -> 'int'
1701 [004] {Parameter} 'Param' -> 'int'
1702 [004] {Variable} 'Var_1' -> 'int'
1703 [004] {Variable} 'Var_2' -> 'int'
1704 [003] {Parameter} 'Param_1' -> 'int'
1705 [003] {Parameter} 'Param_2' -> 'int'
1707 CODEVIEW - MSVC (Windows)
1708 ^^^^^^^^^^^^^^^^^^^^^^^^^
1710 .. code-block:: none
1713 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
1715 [001] {CompileUnit} 'pr-43860.cpp'
1716 [002] {Producer} 'Microsoft (R) Optimizing Compiler'
1717 [002] {Function} extern not_inlined 'InlineFunction' -> 'int'
1719 [004] {Variable} 'Var_2' -> 'int'
1720 [003] {Variable} 'Param' -> 'int'
1721 [003] {Variable} 'Var_1' -> 'int'
1722 [002] {Function} extern not_inlined 'test' -> 'int'
1723 [003] {Variable} 'A' -> 'int'
1724 [003] {Variable} 'Param_1' -> 'int'
1725 [003] {Variable} 'Param_2' -> 'int'
1727 DWARF - Clang (Linux)
1728 ^^^^^^^^^^^^^^^^^^^^^
1730 .. code-block:: none
1733 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
1735 [001] {CompileUnit} 'pr-43860.cpp'
1736 [002] {Producer} 'clang version 14.0.0'
1737 [002] 2 {Function} extern inlined 'InlineFunction' -> 'int'
1739 [004] 5 {Variable} 'Var_2' -> 'int'
1740 [003] 2 {Parameter} 'Param' -> 'int'
1741 [003] 3 {Variable} 'Var_1' -> 'int'
1742 [002] 11 {Function} extern not_inlined 'test' -> 'int'
1743 [003] 12 {Variable} 'A' -> 'int'
1744 [003] 14 {InlinedFunction} inlined 'InlineFunction' -> 'int'
1746 [005] {Variable} 'Var_2' -> 'int'
1747 [004] {Parameter} 'Param' -> 'int'
1748 [004] {Variable} 'Var_1' -> 'int'
1749 [003] 11 {Parameter} 'Param_1' -> 'int'
1750 [003] 11 {Parameter} 'Param_2' -> 'int'
1755 .. code-block:: none
1758 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
1760 [001] {CompileUnit} 'pr-43860.cpp'
1761 [002] {Producer} 'GNU C++14 9.3.0'
1762 [002] 2 {Function} extern declared_inlined 'InlineFunction' -> 'int'
1764 [004] 5 {Variable} 'Var_2' -> 'int'
1765 [003] 2 {Parameter} 'Param' -> 'int'
1766 [003] 3 {Variable} 'Var_1' -> 'int'
1767 [002] 11 {Function} extern not_inlined 'test' -> 'int'
1768 [003] 12 {Variable} 'A' -> 'int'
1769 [003] 13 {InlinedFunction} declared_inlined 'InlineFunction' -> 'int'
1771 [005] {Variable} 'Var_2' -> 'int'
1772 [004] {Parameter} 'Param' -> 'int'
1773 [004] {Variable} 'Var_1' -> 'int'
1774 [003] 11 {Parameter} 'Param_1' -> 'int'
1775 [003] 11 {Parameter} 'Param_2' -> 'int'
1777 From the previous logical views, we can see that the CodeView debug
1778 information generated by the Clang compiler shows the variables **Var_1**
1779 and **Var_2** are at the same lexical scope (**4**) in the function
1780 **InlineFuction**. The DWARF generated by GCC/Clang and CodeView
1781 generated by MSVC, show those variables at the correct lexical scope:
1782 **3** and **4** respectively.
1784 Using the :program:`llvm-debuginfo-analyzer` selection facilities, we
1785 can produce a simple tabular output showing just the logical elements
1786 that have in their name the *var* pattern. The logical view is sorted
1787 by the variables name.
1789 .. code-block:: none
1791 llvm-debuginfo-analyzer --attribute=level,format
1793 --select-regex --select-nocase --select=Var
1798 .. code-block:: none
1801 [000] {File} 'pr-43860-codeview-clang.o' -> COFF-x86-64
1803 [001] {CompileUnit} 'pr-43860.cpp'
1804 [004] {Variable} 'Var_1' -> 'int'
1805 [004] {Variable} 'Var_2' -> 'int'
1808 [000] {File} 'pr-43860-codeview-msvc.o' -> COFF-i386
1810 [001] {CompileUnit} 'pr-43860.cpp'
1811 [003] {Variable} 'Var_1' -> 'int'
1812 [004] {Variable} 'Var_2' -> 'int'
1815 [000] {File} 'pr-43860-dwarf-clang.o' -> elf64-x86-64
1817 [001] {CompileUnit} 'pr-43860.cpp'
1818 [004] {Variable} 'Var_1' -> 'int'
1819 [003] 3 {Variable} 'Var_1' -> 'int'
1820 [005] {Variable} 'Var_2' -> 'int'
1821 [004] 5 {Variable} 'Var_2' -> 'int'
1824 [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64
1826 [001] {CompileUnit} 'pr-43860.cpp'
1827 [004] {Variable} 'Var_1' -> 'int'
1828 [003] 3 {Variable} 'Var_1' -> 'int'
1829 [005] {Variable} 'Var_2' -> 'int'
1830 [004] 5 {Variable} 'Var_2' -> 'int'
1832 It also shows, that the CodeView debug information does not generate
1833 source code line numbers for the those logical symbols. The logical
1834 view is sorted by the types name.
1836 TEST CASE 6 - FULL LOGICAL VIEW
1837 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1838 For advanced users, :program:`llvm-debuginfo-analyzer` can display low
1839 level information that includes offsets within the debug information
1840 section, debug location operands, linkage names, etc.
1842 .. code-block:: none
1844 llvm-debuginfo-analyzer --attribute=all
1849 [0x0000000000][000] {File} 'test-dwarf-clang.o' -> elf64-x86-64
1851 [0x000000000b][001] {CompileUnit} 'test.cpp'
1852 [0x000000000b][002] {Producer} 'clang version 12.0.0'
1855 {Public} 'foo' [0x0000000000:0x000000003a]
1856 [0x000000000b][002] {Range} Lines 2:9 [0x0000000000:0x000000003a]
1857 [0x00000000bc][002] {BaseType} 'bool'
1858 [0x0000000099][002] {BaseType} 'int'
1859 [0x00000000b5][002] {BaseType} 'unsigned int'
1861 [0x00000000a0][002] {Source} '/test.cpp'
1862 [0x00000000a0][002] 1 {TypeAlias} 'INTPTR' -> [0x00000000ab]'* const int'
1863 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1864 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a]
1865 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb'
1866 [0x0000000071][003] {Block}
1867 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f]
1868 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
1869 [0x000000007e][005] {Coverage} 100.00%
1870 [0x000000007f][005] {Location}
1871 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
1872 [0x000000001c][004] 5 {Line} {NewStatement} '/test.cpp'
1873 [0x000000001c][004] {Code} 'movl $0x7, -0x1c(%rbp)'
1874 [0x0000000023][004] 6 {Line} {NewStatement} '/test.cpp'
1875 [0x0000000023][004] {Code} 'movl $0x7, -0x4(%rbp)'
1876 [0x000000002a][004] {Code} 'jmp 0x6'
1877 [0x000000002f][004] 8 {Line} {NewStatement} '/test.cpp'
1878 [0x000000002f][004] {Code} 'movl -0x14(%rbp), %eax'
1879 [0x0000000063][003] 2 {Parameter} 'ParamBool' -> [0x00000000bc]'bool'
1880 [0x0000000063][004] {Coverage} 100.00%
1881 [0x0000000064][004] {Location}
1882 [0x0000000064][005] {Entry} Stack Offset: -21 (0xffffffffffffffeb) [DW_OP_fbreg]
1883 [0x0000000047][003] 2 {Parameter} 'ParamPtr' -> [0x00000000a0]'INTPTR'
1884 [0x0000000047][004] {Coverage} 100.00%
1885 [0x0000000048][004] {Location}
1886 [0x0000000048][005] {Entry} Stack Offset: -16 (0xfffffffffffffff0) [DW_OP_fbreg]
1887 [0x0000000055][003] 2 {Parameter} 'ParamUnsigned' -> [0x00000000b5]'unsigned int'
1888 [0x0000000055][004] {Coverage} 100.00%
1889 [0x0000000056][004] {Location}
1890 [0x0000000056][005] {Entry} Stack Offset: -20 (0xffffffffffffffec) [DW_OP_fbreg]
1891 [0x000000008d][003] 4 {TypeAlias} 'INTEGER' -> [0x0000000099]'int'
1892 [0x0000000000][003] 2 {Line} {NewStatement} '/test.cpp'
1893 [0x0000000000][003] {Code} 'pushq %rbp'
1894 [0x0000000001][003] {Code} 'movq %rsp, %rbp'
1895 [0x0000000004][003] {Code} 'movb %dl, %al'
1896 [0x0000000006][003] {Code} 'movq %rdi, -0x10(%rbp)'
1897 [0x000000000a][003] {Code} 'movl %esi, -0x14(%rbp)'
1898 [0x000000000d][003] {Code} 'andb $0x1, %al'
1899 [0x000000000f][003] {Code} 'movb %al, -0x15(%rbp)'
1900 [0x0000000012][003] 3 {Line} {NewStatement} {PrologueEnd} '/test.cpp'
1901 [0x0000000012][003] {Code} 'testb $0x1, -0x15(%rbp)'
1902 [0x0000000016][003] {Code} 'je 0x13'
1903 [0x0000000032][003] 8 {Line} '/test.cpp'
1904 [0x0000000032][003] {Code} 'movl %eax, -0x4(%rbp)'
1905 [0x0000000035][003] 9 {Line} {NewStatement} '/test.cpp'
1906 [0x0000000035][003] {Code} 'movl -0x4(%rbp), %eax'
1907 [0x0000000038][003] {Code} 'popq %rbp'
1908 [0x0000000039][003] {Code} 'retq'
1909 [0x000000003a][003] 9 {Line} {NewStatement} {EndSequence} '/test.cpp'
1911 -----------------------------
1912 Element Total Printed
1913 -----------------------------
1918 -----------------------------
1922 189 (100.00%) : [0x000000000b][001] {CompileUnit} 'test.cpp'
1923 110 ( 58.20%) : [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1924 27 ( 14.29%) : [0x0000000071][003] {Block}
1926 Totals by lexical level:
1927 [001]: 189 (100.00%)
1928 [002]: 110 ( 58.20%)
1931 The **Scope Sizes** table shows the contribution in bytes to the debug
1932 information by each scope, which can be used to determine unexpected
1933 size changes in the DWARF sections between different versions of the
1936 .. code-block:: none
1938 [0x000000002a][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000099]'int'
1939 [0x000000002a][003] {Range} Lines 2:9 [0x0000000000:0x000000003a]
1940 [0x000000002a][003] {Linkage} 0x2 '_Z3fooPKijb'
1941 [0x0000000071][003] {Block}
1942 [0x0000000071][004] {Range} Lines 5:8 [0x000000001c:0x000000002f]
1943 [0x000000007e][004] 5 {Variable} 'CONSTANT' -> [0x00000000c3]'const INTEGER'
1944 [0x000000007e][005] {Coverage} 100.00%
1945 [0x000000007f][005] {Location}
1946 [0x000000007f][006] {Entry} Stack Offset: -28 (0xffffffffffffffe4) [DW_OP_fbreg]
1948 The **{Range}** attribute describe the line ranges for a logical scope.
1949 For this case, the function **foo** is within the lines **2** and **9**.
1951 The **{Coverage}** and **{Location}** attributes describe the debug
1952 location and coverage for logical symbols. For optimized code, the
1953 coverage value decreases and it affects the program debuggability.
1957 :program:`llvm-debuginfo-analyzer` returns 0 if the input files were
1958 parsed and printed successfully. Otherwise, it returns 1.
1962 :manpage:`llvm-dwarfdump`