Check if debug line sequences are starting after the first code segment
authorAntónio Afonso <antonio.afonso@gmail.com>
Sun, 18 Oct 2020 17:33:25 +0000 (10:33 -0700)
committerAntónio Afonso <antonio.afonso@gmail.com>
Mon, 9 Nov 2020 16:26:00 +0000 (08:26 -0800)
I found a few cases where entries in the debug_line for a specific line of code have invalid entries (the address is outside of a code section or no section at all) and also valid entries. When this happens lldb might not set the breakpoint because the first line entry it will find in the line table might be the invalid one and since it's range is "invalid" no location is resolved. To get around this I changed the way we parse the line sequences to ignore those starting at an address under the first code segment.
Greg suggested to implement it this way so we don't need to check all sections for every line sequence.

Reviewed By: clayborg

Differential Revision: https://reviews.llvm.org/D87172

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml [new file with mode: 0644]

index b19881f..43aa8bc 100644 (file)
@@ -497,6 +497,25 @@ void SymbolFileDWARF::InitializeObject() {
 
   m_index =
       std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this);
+
+  const SectionList *section_list = m_objfile_sp->GetModule()->GetSectionList();
+  if (section_list)
+    InitializeFirstCodeAddress(*section_list);
+}
+
+void SymbolFileDWARF::InitializeFirstCodeAddress(
+    const lldb_private::SectionList &section_list) {
+  const uint32_t num_sections = section_list.GetSize();
+  for (uint32_t i = 0; i < num_sections; ++i) {
+    SectionSP section_sp(section_list.GetSectionAtIndex(i));
+    if (section_sp->GetChildren().GetSize() > 0) {
+      InitializeFirstCodeAddress(section_sp->GetChildren());
+    } else if (section_sp->GetType() == eSectionTypeCode) {
+      const addr_t section_file_address = section_sp->GetFileAddress();
+      if (m_first_code_address > section_file_address)
+        m_first_code_address = section_file_address;
+    }
+  }
 }
 
 bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
@@ -1040,6 +1059,12 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
   // The Sequences view contains only valid line sequences. Don't iterate over
   // the Rows directly.
   for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) {
+    // Ignore line sequences that do not start after the first code address.
+    // All addresses generated in a sequence are incremental so we only need
+    // to check the first one of the sequence. Check the comment at the
+    // m_first_code_address declaration for more details on this.
+    if (seq.LowPC < m_first_code_address)
+      continue;
     std::unique_ptr<LineSequence> sequence =
         LineTable::CreateLineSequenceContainer();
     for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) {
index 019f76c..56c803e 100644 (file)
@@ -482,6 +482,9 @@ protected:
 
   const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
 
+  void
+  InitializeFirstCodeAddress(const lldb_private::SectionList &section_list);
+
   lldb::ModuleWP m_debug_map_module_wp;
   SymbolFileDWARFDebugMap *m_debug_map_symfile;
 
@@ -517,6 +520,13 @@ protected:
   llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
       m_type_unit_support_files;
   std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
+  /// DWARF does not provide a good way for traditional (concatenating) linkers
+  /// to invalidate debug info describing dead-stripped code. These linkers will
+  /// keep the debug info but resolve any addresses referring to such code as
+  /// zero (BFD), a small positive integer (zero + relocation addend -- GOLD),
+  /// or -1/-2 (LLD). Try to filter out this debug info by comparing it to the
+  /// lowest code address in the module.
+  lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
diff --git a/lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml b/lldb/test/Shell/SymbolFile/DWARF/line-entries-invalid-addresses.yaml
new file mode 100644 (file)
index 0000000..0714302
--- /dev/null
@@ -0,0 +1,421 @@
+# RUN: yaml2obj %s > %t
+# RUN: %lldb %t -b -o "image lookup -f main.cpp -l 2 -v" | FileCheck %s
+# CHECK: 1 match found in main.cpp:2 {{.*}}
+# CHECK: LineEntry: {{.*}}main.cpp:2:{{.*}}
+
+# int foo() {
+#     return 42;
+# }
+#
+# int main() {
+#     int x = foo();
+#     return x;
+# }
+# dwarfdump -debug-line:
+# Address            Line   Column File   ISA Discriminator Flags
+# ------------------ ------ ------ ------ --- ------------- -------------
+# 0x0000000100000f80      1      0      1   0             0  is_stmt
+# 0x0000000100000f84      2      5      1   0             0  is_stmt prologue_end
+# 0x0000000100000f8b      2      5      1   0             0  is_stmt end_sequence
+# 0x0000000100000f90      5      0      1   0             0  is_stmt
+# 0x0000000100000f90      5      0      1   0             0  is_stmt end_sequence
+# 0x000000000000000f      2     13      1   0             0  is_stmt prologue_end
+# 0x0000000000000014      2      9      1   0             0
+# 0x0000000000000017      3     12      1   0             0  is_stmt
+# 0x000000000000001d      3     12      1   0             0  end_sequence
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x0000000A
+  ncmds:           7
+  sizeofcmds:      1400
+  flags:           0x00000000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            605D6BBF-4DB2-39F7-8068-F9BB3896DF0C
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         24
+    platform:        1
+    minos:           659200
+    sdk:             659206
+    ntools:          0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          4096
+    nsyms:           3
+    stroff:          4144
+    strsize:         37
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          1
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          4096
+    fileoff:         0
+    filesize:        0
+    maxprot:         5
+    initprot:        5
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000100000F80
+        size:            48
+        offset:          0x00000000
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000605D6BBF4DB239F7
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x0000000100000FB0
+        size:            72
+        offset:          0x00000000
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         CFFAEDFE07000001030000000A000000070000007805000000000000000000001B00000018000000605D6BBF4DB239F78068F9BB3896DF0C320000001800000001000000000F0A00
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294971392
+    vmsize:          4096
+    fileoff:         4096
+    filesize:        85
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         952
+    segname:         __DWARF
+    vmaddr:          4294975488
+    vmsize:          4096
+    fileoff:         8192
+    filesize:        839
+    maxprot:         7
+    initprot:        3
+    nsects:          4
+    flags:           0
+    Sections:
+      - sectname:        __debug_line
+        segname:         __DWARF
+        addr:            0x0000000100002000
+        size:            96
+        offset:          0x00002000
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x00000001000020E9
+        size:            119
+        offset:          0x000020E9
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_abbrev
+        segname:         __DWARF
+        addr:            0x0000000100002160
+        size:            90
+        offset:          0x00002160
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_str
+        segname:         __DWARF
+        addr:            0x00000001000021BA
+        size:            130
+        offset:          0x000021BA
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+LinkEditData:
+  NameList:
+    - n_strx:          2
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971264
+    - n_strx:          11
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          31
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971280
+  StringTable:
+    - ''
+    - ''
+    - __Z3foov
+    - __mh_execute_header
+    - _main
+DWARF:
+  debug_str:
+    - ''
+    - 'Apple clang version 11.0.3 (clang-1103.0.32.62)'
+    - main.cpp
+    - '/Users/aadsm/toolchain_dev/external/llvm-project'
+    - _Z3foov
+    - foo
+    - main
+    - x
+    - int
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x0000000000000001
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_producer
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_stmt_list
+              Form:            DW_FORM_sec_offset
+            - Attribute:       DW_AT_comp_dir
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_data4
+        - Code:            0x0000000000000002
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_data4
+            - Attribute:       DW_AT_frame_base
+              Form:            DW_FORM_exprloc
+            - Attribute:       DW_AT_linkage_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+            - Attribute:       DW_AT_external
+              Form:            DW_FORM_flag_present
+        - Code:            0x0000000000000003
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_low_pc
+              Form:            DW_FORM_addr
+            - Attribute:       DW_AT_high_pc
+              Form:            DW_FORM_data4
+            - Attribute:       DW_AT_frame_base
+              Form:            DW_FORM_exprloc
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+            - Attribute:       DW_AT_external
+              Form:            DW_FORM_flag_present
+        - Code:            0x0000000000000004
+          Tag:             DW_TAG_variable
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_location
+              Form:            DW_FORM_exprloc
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref_addr
+        - Code:            0x0000000000000005
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+  debug_info:
+    - Length:          0x0000000000000073
+      Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0000000000000000
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x00000001
+          Values:
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000004
+            - Value:           0x0000000000000031
+            - Value:           0x0000000000000000
+            - Value:           0x000000000000003A
+            - Value:           0x0000000100000F80
+            - Value:           0x0000000000000030
+        - AbbrCode:        0x00000002
+          Values:
+            - Value:           0x0000000100000F80
+            - Value:           0x000000000000000B
+            - Value:           0x0000000000000001
+              BlockData:       [ 0x56 ]
+            - Value:           0x000000000000006B
+            - Value:           0x0000000000000073
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000001
+            - Value:           0x000000000000006F
+            - Value:           0x0000000000000001
+        - AbbrCode:        0x00000003
+          Values:
+            - Value:           0x0000000100000F90
+            - Value:           0x0000000000000020
+            - Value:           0x0000000000000001
+              BlockData:       [ 0x56 ]
+            - Value:           0x0000000000000077
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000005
+            - Value:           0x000000000000006F
+            - Value:           0x0000000000000001
+        - AbbrCode:        0x00000004
+          Values:
+            - Value:           0x0000000000000002
+              BlockData:       [ 0x91, 0x78 ]
+            - Value:           0x000000000000007C
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000006
+            - Value:           0x000000000000006F
+        - AbbrCode:        0x00000000
+        - AbbrCode:        0x00000005
+          Values:
+            - Value:           0x000000000000007E
+            - Value:           0x0000000000000005
+            - Value:           0x0000000000000004
+        - AbbrCode:        0x00000000
+  debug_line:
+    - Length:          92
+      Version:         4
+      PrologueLength:  32
+      MinInstLength:   1
+      MaxOpsPerInst:   1
+      DefaultIsStmt:   1
+      LineBase:        251
+      LineRange:       14
+      OpcodeBase:      13
+      StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
+      IncludeDirs:     []
+      Files:
+        - Name:            main.cpp
+          DirIdx:          0
+          ModTime:         0
+          Length:          0
+      Opcodes:
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            4294971264
+        - Opcode:          DW_LNS_copy
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            5
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            0
+        - Opcode:          0x4B
+          Data:            0
+        - Opcode:          DW_LNS_advance_pc
+          Data:            7
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+          # Sequence manually added (not produced by the source code)
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            4294971280
+        - Opcode:          0x16
+          Data:            0
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+          # Sequence manually added (not produced by the source code)
+        - Opcode:          DW_LNS_set_column
+          Data:            13
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            0
+        - Opcode:          0xE5
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            9
+        - Opcode:          DW_LNS_negate_stmt
+          Data:            0
+        - Opcode:          0x58
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            12
+        - Opcode:          DW_LNS_negate_stmt
+          Data:            0
+        - Opcode:          0x3D
+          Data:            0
+        - Opcode:          DW_LNS_negate_stmt
+          Data:            0
+        - Opcode:          DW_LNS_advance_pc
+          Data:            6
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+...