Index: packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py =================================================================== --- packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py +++ packages/Python/lldbsuite/test/python_api/symbol-context/two-files/TestSymbolContextTwoFiles.py @@ -38,3 +38,46 @@ symbol_address, lldb.eSymbolContextFunction) self.assertEqual(symbol_name, sc_by_address.GetFunction().GetName()) + + @add_test_categories(['pyapi']) + def test_ranges_in_multiple_compile_unit(self): + """This test verifies that we correctly handle the case when multiple + compile unit contains DW_AT_ranges and DW_AT_ranges_base attributes.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + source1 = "file1.cpp" + line1 = line_number(source1, '// Break1') + breakpoint1 = target.BreakpointCreateByLocation(source1, line1) + self.assertIsNotNone(breakpoint1) + self.assertTrue(breakpoint1.IsValid()) + + source2 = "file2.cpp" + line2 = line_number(source2, '// Break2') + breakpoint2 = target.BreakpointCreateByLocation(source2, line2) + self.assertIsNotNone(breakpoint2) + self.assertTrue(breakpoint2.IsValid()) + + process = target.LaunchSimple(None, None, os.getcwd()) + self.assertIsNotNone(process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint2) + self.assertEqual(len(threads), 1) + frame = threads[0].GetFrameAtIndex(0) + value = frame.FindVariable("x") + self.assertTrue(value.IsValid()) + + process.Continue() + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint1) + self.assertEqual(len(threads), 1) + frame = threads[0].GetFrameAtIndex(0) + value = frame.FindVariable("x") + self.assertTrue(value.IsValid()) + + process.Continue() Index: packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h =================================================================== --- packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h +++ packages/Python/lldbsuite/test/python_api/symbol-context/two-files/decls.h @@ -1,11 +1,11 @@ -struct struct1 -{ - static void - f(); +struct struct1 { + ~struct1(); + static void f(); }; -struct struct2 -{ - static void - f(); +struct struct2 { + ~struct2(); + static void f(); }; + +int g(); Index: packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp =================================================================== --- packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp +++ packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file1.cpp @@ -1,13 +1,21 @@ #include "decls.h" -void -struct1::f() -{ +int g() { + return 1; } -int main() -{ - struct1::f(); - struct2::f(); - return 0; +struct1::~struct1() { + int x = g(); // Break1 +} + +void struct1::f() {} + +int main() { + struct1::f(); + struct2::f(); + + struct1 s1; + struct2 s2; + + return 0; } Index: packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp =================================================================== --- packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp +++ packages/Python/lldbsuite/test/python_api/symbol-context/two-files/file2.cpp @@ -1,6 +1,7 @@ #include "decls.h" -void -struct2::f() -{ +struct2::~struct2() { + int x = g(); // Break2 } + +void struct2::f() {} Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -70,7 +70,8 @@ uint8_t GetAddressByteSize() const { return m_addr_size; } dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_addr_t GetAddrBase() const { return m_addr_base; } - void SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset); + dw_addr_t GetRangesBase() const { return m_ranges_base; } + void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, dw_offset_t base_obj_offset); void ClearDIEs(bool keep_compile_unit_die); void BuildAddressRangeTable(SymbolFileDWARF *dwarf2Data, DWARFDebugAranges *debug_aranges); @@ -185,10 +186,11 @@ lldb::LanguageType m_language_type; bool m_is_dwarf64; lldb_private::LazyBool m_is_optimized; - dw_addr_t m_addr_base; // Value of DW_AT_addr_base - dw_offset_t - m_base_obj_offset; // If this is a dwo compile unit this is the offset of - // the base compile unit in the main object file + dw_addr_t m_addr_base; // Value of DW_AT_addr_base + dw_addr_t m_ranges_base; // Value of DW_AT_ranges_base + dw_offset_t m_base_obj_offset; // If this is a dwo compile unit this is the + // offset of the base compile unit in the main + // object file void ParseProducerInfo(); Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -46,7 +46,7 @@ m_producer_version_minor(0), m_producer_version_update(0), m_language_type(eLanguageTypeUnknown), m_is_dwarf64(false), m_is_optimized(eLazyBoolCalculate), m_addr_base(0), - m_base_obj_offset(DW_INVALID_OFFSET) {} + m_ranges_base(0), m_base_obj_offset(DW_INVALID_OFFSET) {} DWARFCompileUnit::~DWARFCompileUnit() {} @@ -307,7 +307,9 @@ dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( m_dwarf2Data, this, DW_AT_GNU_addr_base, 0); - dwo_cu->SetAddrBase(addr_base, m_offset); + dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf2Data, this, DW_AT_GNU_ranges_base, 0); + dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset); } dw_offset_t DWARFCompileUnit::GetAbbrevOffset() const { @@ -1114,8 +1116,10 @@ } void DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, + dw_addr_t ranges_base, dw_offset_t base_obj_offset) { m_addr_base = addr_base; + m_ranges_base = ranges_base; m_base_obj_offset = base_obj_offset; } Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -450,7 +450,7 @@ case DW_AT_ranges: { const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); if (debug_ranges) { - debug_ranges->FindRanges(form_value.Unsigned(), ranges); + debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges); // All DW_AT_ranges are relative to the base address of the // compile unit. We add the compile unit base address to make // sure all the addresses are properly fixed up. @@ -1108,7 +1108,7 @@ if (debug_ranges_offset != DW_INVALID_OFFSET) { DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(debug_ranges_offset, ranges); + debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); ranges.Slide(cu->GetBaseAddress()); } else if (check_hi_lo_pc) { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; @@ -1772,7 +1772,7 @@ if (debug_ranges_offset != DW_INVALID_OFFSET) { DWARFRangeList ranges; DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(debug_ranges_offset, ranges); + debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); // All DW_AT_ranges are relative to the base address of the // compile unit. We add the compile unit base address to make // sure all the addresses are properly fixed up. Index: source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -23,7 +23,8 @@ static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); - bool FindRanges(dw_offset_t debug_ranges_offset, + bool FindRanges(dw_addr_t debug_ranges_base, + dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const; protected: Index: source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -118,9 +118,11 @@ } } -bool DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, +bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, + dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const { - range_map_const_iterator pos = m_range_map.find(debug_ranges_offset); + dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset; + range_map_const_iterator pos = m_range_map.find(debug_ranges_address); if (pos != m_range_map.end()) { range_list = pos->second; return true; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3810,7 +3810,8 @@ if (form_value.Form() == DW_FORM_sec_offset) { DWARFRangeList dwarf_scope_ranges; const DWARFDebugRanges *debug_ranges = DebugRanges(); - debug_ranges->FindRanges(form_value.Unsigned(), + debug_ranges->FindRanges(die.GetCU()->GetRangesBase(), + form_value.Unsigned(), dwarf_scope_ranges); // All DW_AT_start_scope are relative to the base address of the