Check if debug line sequences are starting after the first code segment

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
This commit is contained in:
António Afonso 2020-10-18 10:33:25 -07:00
parent d5a465866e
commit 265a38fbc5
3 changed files with 456 additions and 0 deletions

View 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) {

View 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

View File

@ -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
...