diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -335,6 +335,37 @@ } else { line_entry.range.GetBaseAddress().CalculateSymbolContext(&sc, resolve_scope); + // Sometimes debug info is bad and isn't able to resolve the line entry's + // address back to the same compile unit and/or line entry. If the compile + // unit changed, then revert back to just the compile unit and line entry. + // Prior to this fix, the above code might end up not being able to lookup + // the address, and then it would clear compile unit and the line entry in + // the symbol context and the breakpoint would fail to get set even though + // we have a valid line table entry in this compile unit. The address + // lookup can also end up finding another function in another compiler + // unit if the DWARF has overlappging address ranges. So if we end up with + // no compile unit or a different one after the above function call, + // revert back to the same results as if resolve_scope was set exactly to + // eSymbolContextLineEntry. + if (sc.comp_unit != this) { + if (sc.comp_unit == nullptr && sc.module_sp) { + // Only report an error if we don't map back to any compile unit. With + // link time optimizations, the debug info might have many compile + // units that have the same address range due to function outlining + // or other link time optimizations. If the compile unit is NULL, then + // address resolving is completely failing and more deserving of an + // error message the user can see. + sc.module_sp->ReportError( + "unable to resolve a line table file address 0x%" PRIx64 " back " + "to a compile unit, please file a bug and attach the address " + "and file.", line_entry.range.GetBaseAddress().GetFileAddress()); + } + // Revert to equivalent of resolve_scope == eSymbolContextLineEntry. + sc.comp_unit = this; + sc.function = nullptr; + sc.block = nullptr; + sc.line_entry = line_entry; + } } sc_list.Append(sc); diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py --- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py @@ -106,6 +106,44 @@ 'Incorrectly resolved a breakpoint using full path "%s" with ' 'debug info that has relative path with matching suffix' % (path)) + @skipIf(oslist=["windows"]) + @no_debug_info_test + def test_breakpoints_with_bad_aranges(self): + """ + Test that we can set breakpoints in a file that has an invalid + .debug_aranges. Older versions of LLDB would find a line entry + in the line table and then would use the start address of the line + entry to do an address lookup on the entry from the line table. If + this address to symbol context lookup would fail, due to a bad + .debug_aranges, it would cause the breakpoint to not get resolved. + Verify that even in these conditions we are able to resolve a + breakpoint. + + The "bad_aranges.yaml" contains a line table that is: + + Line table for /tmp/ab/main.cpp in `a.out + 0x0000000100003f94: /tmp/ab/main.cpp:1 + 0x0000000100003fb0: /tmp/ab/main.cpp:2:3 + 0x0000000100003fb8: /tmp/ab/main.cpp:2:3 + + The .debug_aranges has one range for this compile unit that is + invalid: [0x0000000200003f94-0x0000000200003fb8). This will cause + the resolving of the addresses to fail. + """ + src_dir = self.getSourceDir() + yaml_path = os.path.join(src_dir, "bad_aranges.yaml") + yaml_base, ext = os.path.splitext(yaml_path) + obj_path = self.getBuildArtifact("a.out") + self.yaml2obj(yaml_path, obj_path) + + # Create a target with the object file we just created from YAML + target = self.dbg.CreateTarget(obj_path) + src_path = '/tmp/ab/main.cpp' + bkpt = target.BreakpointCreateByLocation(src_path, 2) + self.assertTrue(bkpt.GetNumLocations() > 0, + 'Couldn\'t resolve breakpoint using "%s" in executate "%s" with ' + 'debug info that has a bad .debug_aranges section' % (src_path, self.getBuildArtifact("a.out"))) + def setUp(self): # Call super's setUp(). diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/bad_aranges.yaml b/lldb/test/API/functionalities/breakpoint/breakpoint_command/bad_aranges.yaml new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/bad_aranges.yaml @@ -0,0 +1,445 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0xA + ncmds: 7 + sizeofcmds: 1240 + flags: 0x0 + reserved: 0x0 +LoadCommands: + - cmd: LC_UUID + cmdsize: 24 + uuid: 030921EA-6D76-3A68-B515-386B9AF6D568 + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 1 + minos: 786432 + sdk: 787200 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4096 + nsyms: 2 + stroff: 4128 + strsize: 28 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 16384 + fileoff: 0 + filesize: 0 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x100003F94 + size: 36 + offset: 0x0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: CFFAEDFE0C000001000000000A00000007000000D804000000000000000000001B000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x100003FB8 + size: 72 + offset: 0x0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: CFFAEDFE0C000001000000000A00000007000000D804000000000000000000001B00000018000000030921EA6D763A68B515386B9AF6D56832000000180000000100000000000C00 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294983680 + vmsize: 4096 + fileoff: 4096 + filesize: 60 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 792 + segname: __DWARF + vmaddr: 4294987776 + vmsize: 4096 + fileoff: 8192 + filesize: 796 + maxprot: 7 + initprot: 3 + nsects: 9 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x100005000 + size: 64 + offset: 0x2000 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - sectname: __debug_aranges + segname: __DWARF + addr: 0x100005040 + size: 48 + offset: 0x2040 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - sectname: __debug_info + segname: __DWARF + addr: 0x100005070 + size: 148 + offset: 0x2070 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x100005104 + size: 90 + offset: 0x2104 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - sectname: __debug_str + segname: __DWARF + addr: 0x10000515E + size: 200 + offset: 0x215E + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + - sectname: __apple_names + segname: __DWARF + addr: 0x100005226 + size: 60 + offset: 0x2226 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 485341480100000001000000010000000C000000000000000100000001000600000000006A7F9A7C2C000000AB000000010000003200000000000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x100005262 + size: 36 + offset: 0x2262 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF + - sectname: __apple_types + segname: __DWARF + addr: 0x100005286 + size: 114 + offset: 0x2286 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 48534148010000000200000002000000180000000000000004000000010006000300050005000B000600060000000000010000003080880B6320957C440000005B000000BF0000000100000076000000240000A4283A0C00000000C3000000010000008C00000024000057D77B9300000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x1000052F8 + size: 36 + offset: 0x22F8 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF +LinkEditData: + NameList: + - n_strx: 2 + n_type: 0xF + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 4294983572 + StringTable: + - '' + - '' + - __mh_execute_header + - _main +DWARF: + debug_str: + - '' + - 'Apple clang version 13.1.6 (clang-1316.0.21.2)' + - main.cpp + - '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk' + - MacOSX.sdk + - '/tmp/ab' + - main + - argc + - argv + - envp + - int + - char + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + 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_LLVM_sysroot + Form: DW_FORM_strp + - Attribute: DW_AT_APPLE_sdk + 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: 0x2 + 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_APPLE_omit_frame_ptr + Form: DW_FORM_flag_present + - 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: 0x3 + Tag: DW_TAG_formal_parameter + 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: 0x4 + 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 + - Code: 0x5 + Tag: DW_TAG_pointer_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + - Code: 0x6 + Tag: DW_TAG_const_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref_addr + debug_aranges: + - Length: 0x2C + Version: 2 + CuOffset: 0x0 + AddressSize: 0x8 + Descriptors: + - Address: 0x200003F94 + Length: 0x24 + debug_info: + - Length: 0x90 + Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0x0 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x1 + - Value: 0x1A + - Value: 0x30 + - Value: 0x39 + - Value: 0x98 + - Value: 0x0 + - Value: 0xA3 + - Value: 0x100003F94 + - Value: 0x24 + - AbbrCode: 0x2 + Values: + - Value: 0x100003F94 + - Value: 0x24 + - Value: 0x1 + - Value: 0x1 + BlockData: [ 0x6F ] + - Value: 0xAB + - Value: 0x1 + - Value: 0x1 + - Value: 0x76 + - Value: 0x1 + - AbbrCode: 0x3 + Values: + - Value: 0x2 + BlockData: [ 0x91, 0x18 ] + - Value: 0xB0 + - Value: 0x1 + - Value: 0x1 + - Value: 0x76 + - AbbrCode: 0x3 + Values: + - Value: 0x2 + BlockData: [ 0x91, 0x10 ] + - Value: 0xB5 + - Value: 0x1 + - Value: 0x1 + - Value: 0x7D + - AbbrCode: 0x3 + Values: + - Value: 0x2 + BlockData: [ 0x91, 0x8 ] + - Value: 0xBA + - Value: 0x1 + - Value: 0x1 + - Value: 0x7D + - AbbrCode: 0x0 + - AbbrCode: 0x4 + Values: + - Value: 0xBF + - Value: 0x5 + - Value: 0x4 + - AbbrCode: 0x5 + Values: + - Value: 0x82 + - AbbrCode: 0x5 + Values: + - Value: 0x87 + - AbbrCode: 0x6 + Values: + - Value: 0x8C + - AbbrCode: 0x4 + Values: + - Value: 0xC3 + - Value: 0x6 + - Value: 0x1 + - AbbrCode: 0x0 + debug_line: + - Length: 60 + 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 ] + Files: + - Name: main.cpp + DirIdx: 0 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4294983572 + - Opcode: DW_LNS_copy + Data: 0 + - Opcode: DW_LNS_set_column + Data: 3 + - Opcode: DW_LNS_set_prologue_end + Data: 0 + - Opcode: DW_LNS_const_add_pc + Data: 0 + - Opcode: 0xAD + Data: 0 + - Opcode: DW_LNS_advance_pc + Data: 8 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 0 +...