Mac dump_syms: accept __DWARF segment without __debug_info section
A .dSYM may validly contain a __DWARF segment without any __debug_info section. This can occur for Chromium Framework in a component build of Chromium, because in that case, all of the code is in other libraries that Chromium Framework depends on. This was previously tested by an assertion, but the assertion did not trigger in NDEBUG (release) builds. In NDEBUG builds, this condition would lead to an out-of-bounds read, detected by AddressSanitizer. Instead of an assertion, the check is now always done at runtime. Instead of being fatal, it's now just a warning, because it's been established that __DWARF without __debug_info can occur. (In the Chromium case, it remains pointless to run dump_syms via the "chrome_dump_syms" target on a component build, as it'll only attempt to symbolize Chromium Framework, and not any of the libraries that Chromium Framework depends on that actually contain the code.) Bug: chromium:991206 Change-Id: I6c9c75f0be7901813e3eaae54aff38c1afe73ca9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1741610 Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
ef04c9c028
commit
01dfa81f1b
2 changed files with 8 additions and 15 deletions
|
@ -413,7 +413,7 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr<Module>& module) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
|
void DumpSymbols::ReadDwarf(google_breakpad::Module *module,
|
||||||
const mach_o::Reader &macho_reader,
|
const mach_o::Reader &macho_reader,
|
||||||
const mach_o::SectionMap &dwarf_sections,
|
const mach_o::SectionMap &dwarf_sections,
|
||||||
bool handle_inter_cu_refs) const {
|
bool handle_inter_cu_refs) const {
|
||||||
|
@ -439,15 +439,14 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
|
||||||
// Find the __debug_info section.
|
// Find the __debug_info section.
|
||||||
dwarf2reader::SectionMap::const_iterator debug_info_entry =
|
dwarf2reader::SectionMap::const_iterator debug_info_entry =
|
||||||
file_context.section_map().find("__debug_info");
|
file_context.section_map().find("__debug_info");
|
||||||
assert(debug_info_entry != file_context.section_map().end());
|
|
||||||
const std::pair<const uint8_t *, uint64>& debug_info_section =
|
|
||||||
debug_info_entry->second;
|
|
||||||
// There had better be a __debug_info section!
|
// There had better be a __debug_info section!
|
||||||
if (!debug_info_section.first) {
|
if (debug_info_entry == file_context.section_map().end()) {
|
||||||
fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n",
|
fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n",
|
||||||
selected_object_name_.c_str());
|
selected_object_name_.c_str());
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
const std::pair<const uint8_t*, uint64>& debug_info_section =
|
||||||
|
debug_info_entry->second;
|
||||||
|
|
||||||
// Build a line-to-module loader for the root handler to use.
|
// Build a line-to-module loader for the root handler to use.
|
||||||
DumperLineToModule line_to_module(&byte_reader);
|
DumperLineToModule line_to_module(&byte_reader);
|
||||||
|
@ -484,8 +483,6 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
|
||||||
// Process the entire compilation unit; get the offset of the next.
|
// Process the entire compilation unit; get the offset of the next.
|
||||||
offset += dwarf_reader.Start();
|
offset += dwarf_reader.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DumpSymbols::ReadCFI(google_breakpad::Module *module,
|
bool DumpSymbols::ReadCFI(google_breakpad::Module *module,
|
||||||
|
@ -598,10 +595,7 @@ bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
|
||||||
|
|
||||||
if (segment.name == "__DWARF") {
|
if (segment.name == "__DWARF") {
|
||||||
if (symbol_data_ != ONLY_CFI) {
|
if (symbol_data_ != ONLY_CFI) {
|
||||||
if (!dumper_.ReadDwarf(module_, reader_, section_map,
|
dumper_.ReadDwarf(module_, reader_, section_map, handle_inter_cu_refs_);
|
||||||
handle_inter_cu_refs_)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (symbol_data_ != NO_CFI) {
|
if (symbol_data_ != NO_CFI) {
|
||||||
mach_o::SectionMap::const_iterator debug_frame
|
mach_o::SectionMap::const_iterator debug_frame
|
||||||
|
|
|
@ -141,9 +141,8 @@ class DumpSymbols {
|
||||||
bool CreateEmptyModule(scoped_ptr<Module>& module);
|
bool CreateEmptyModule(scoped_ptr<Module>& module);
|
||||||
|
|
||||||
// Read debugging information from |dwarf_sections|, which was taken from
|
// Read debugging information from |dwarf_sections|, which was taken from
|
||||||
// |macho_reader|, and add it to |module|. On success, return true;
|
// |macho_reader|, and add it to |module|.
|
||||||
// on failure, report the problem and return false.
|
void ReadDwarf(google_breakpad::Module *module,
|
||||||
bool ReadDwarf(google_breakpad::Module *module,
|
|
||||||
const mach_o::Reader &macho_reader,
|
const mach_o::Reader &macho_reader,
|
||||||
const mach_o::SectionMap &dwarf_sections,
|
const mach_o::SectionMap &dwarf_sections,
|
||||||
bool handle_inter_cu_refs) const;
|
bool handle_inter_cu_refs) const;
|
||||||
|
|
Loading…
Reference in a new issue