From 01dfa81f1b4becb157ed9ccc9277f6eac1de67e3 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Wed, 7 Aug 2019 12:42:38 -0400 Subject: [PATCH] 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 --- src/common/mac/dump_syms.cc | 18 ++++++------------ src/common/mac/dump_syms.h | 5 ++--- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index fef489d0..5ebe3d2a 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -413,7 +413,7 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { 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::SectionMap &dwarf_sections, bool handle_inter_cu_refs) const { @@ -439,15 +439,14 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module, // Find the __debug_info section. dwarf2reader::SectionMap::const_iterator debug_info_entry = file_context.section_map().find("__debug_info"); - assert(debug_info_entry != file_context.section_map().end()); - const std::pair& debug_info_section = - debug_info_entry->second; // 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", selected_object_name_.c_str()); - return false; + return; } + const std::pair& debug_info_section = + debug_info_entry->second; // Build a line-to-module loader for the root handler to use. 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. offset += dwarf_reader.Start(); } - - return true; } bool DumpSymbols::ReadCFI(google_breakpad::Module *module, @@ -598,10 +595,7 @@ bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) { if (segment.name == "__DWARF") { if (symbol_data_ != ONLY_CFI) { - if (!dumper_.ReadDwarf(module_, reader_, section_map, - handle_inter_cu_refs_)) { - return false; - } + dumper_.ReadDwarf(module_, reader_, section_map, handle_inter_cu_refs_); } if (symbol_data_ != NO_CFI) { mach_o::SectionMap::const_iterator debug_frame diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h index ab8a99d1..1e57f86d 100644 --- a/src/common/mac/dump_syms.h +++ b/src/common/mac/dump_syms.h @@ -141,9 +141,8 @@ class DumpSymbols { bool CreateEmptyModule(scoped_ptr& module); // Read debugging information from |dwarf_sections|, which was taken from - // |macho_reader|, and add it to |module|. On success, return true; - // on failure, report the problem and return false. - bool ReadDwarf(google_breakpad::Module *module, + // |macho_reader|, and add it to |module|. + void ReadDwarf(google_breakpad::Module *module, const mach_o::Reader &macho_reader, const mach_o::SectionMap &dwarf_sections, bool handle_inter_cu_refs) const;