From 30020c0d4706a76ea574225650062c6bdb3e67ac Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Thu, 16 Sep 2021 15:50:35 -0700 Subject: [PATCH] Use -d flag enable procecessing DW_TAG_inlined_subroutine This change makes sure dump_syms process DW_TAG_inlined_subroutine only when -d flag is given, which save memory and time when -d is not given. Before this, it always processes DW_TAG_inlined_subroutine and -d determines whether or not to emit INLINE records. Bug: chromium:1250351, chromium:1246974 Change-Id: I54725ba1e513cafe17268ca389ff8acc9c11b25e Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3166674 Reviewed-by: Joshua Peraza --- src/common/dwarf/dwarf2diehandler.h | 9 ++++--- src/common/dwarf_cu_to_module.cc | 37 ++++++++++++++++----------- src/common/dwarf_cu_to_module.h | 3 ++- src/common/linux/dump_symbols.cc | 6 +++-- src/common/mac/dump_syms.cc | 3 ++- src/common/module.cc | 39 +++++++++++++---------------- 6 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/common/dwarf/dwarf2diehandler.h b/src/common/dwarf/dwarf2diehandler.h index bd8008dd..5e568eb8 100644 --- a/src/common/dwarf/dwarf2diehandler.h +++ b/src/common/dwarf/dwarf2diehandler.h @@ -258,10 +258,13 @@ class DIEHandler { // A subclass of DIEHandler, with additional kludges for handling the // compilation unit's root die. -class RootDIEHandler: public DIEHandler { +class RootDIEHandler : public DIEHandler { public: - RootDIEHandler() { } - virtual ~RootDIEHandler() { } + bool handle_inline; + + explicit RootDIEHandler(bool handle_inline = false) + : handle_inline(handle_inline) {} + virtual ~RootDIEHandler() {} // We pass the values reported via Dwarf2Handler::StartCompilationUnit // to this member function, and skip the entire compilation unit if it diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc index dacc9cbe..85be3220 100644 --- a/src/common/dwarf_cu_to_module.cc +++ b/src/common/dwarf_cu_to_module.cc @@ -766,11 +766,12 @@ void DwarfCUToModule::InlineHandler::Finish() { class DwarfCUToModule::FuncHandler: public GenericDIEHandler { public: FuncHandler(CUContext* cu_context, DIEContext* parent_context, - uint64_t offset) + uint64_t offset, bool handle_inline) : GenericDIEHandler(cu_context, parent_context, offset), low_pc_(0), high_pc_(0), high_pc_form_(DW_FORM_addr), ranges_form_(DW_FORM_sec_offset), ranges_data_(0), - decl_file_data_(UINT64_MAX), inline_(false) { } + decl_file_data_(UINT64_MAX), inline_(false), + handle_inline_(handle_inline) { } void ProcessAttributeUnsigned(enum DwarfAttribute attr, enum DwarfForm form, @@ -794,6 +795,7 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler { uint64_t decl_file_data_; bool inline_; vector> child_inlines_; + bool handle_inline_; }; void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned( @@ -844,8 +846,9 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler( enum DwarfTag tag) { switch (tag) { case DW_TAG_inlined_subroutine: - return new InlineHandler(cu_context_, new DIEContext(), offset, 0, - child_inlines_); + if (handle_inline_) + return new InlineHandler(cu_context_, new DIEContext(), offset, 0, + child_inlines_); default: return NULL; } @@ -949,7 +952,8 @@ void DwarfCUToModule::FuncHandler::Finish() { // Only keep track of DW_TAG_subprogram which have the attributes we are // interested. - if (!empty_range || inline_ || decl_file_data_ != UINT64_MAX) { + if (handle_inline_ && + (!empty_range || inline_ || decl_file_data_ != UINT64_MAX)) { uint64_t offset = specification_offset_ != 0 ? specification_offset_ : offset_; cu_context_->file_context->file_private_->inline_origin_map.SetReference( @@ -967,13 +971,14 @@ void DwarfCUToModule::FuncHandler::Finish() { class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { public: NamedScopeHandler(CUContext* cu_context, DIEContext* parent_context, - uint64_t offset) + uint64_t offset, bool handle_inline) : GenericDIEHandler(cu_context, parent_context, offset) { } bool EndAttributes(); DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag); private: DIEContext child_context_; // A context for our children. + bool handle_inline_; }; bool DwarfCUToModule::NamedScopeHandler::EndAttributes() { @@ -986,12 +991,14 @@ DIEHandler* DwarfCUToModule::NamedScopeHandler::FindChildHandler( enum DwarfTag tag) { switch (tag) { case DW_TAG_subprogram: - return new FuncHandler(cu_context_, &child_context_, offset); + return new FuncHandler(cu_context_, &child_context_, offset, + handle_inline_); case DW_TAG_namespace: case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - return new NamedScopeHandler(cu_context_, &child_context_, offset); + return new NamedScopeHandler(cu_context_, &child_context_, offset, + handle_inline_); default: return NULL; } @@ -1101,12 +1108,13 @@ void DwarfCUToModule::WarningReporter::MissingRanges() { DwarfCUToModule::DwarfCUToModule(FileContext* file_context, LineToModuleHandler* line_reader, RangesHandler* ranges_handler, - WarningReporter* reporter) - : line_reader_(line_reader), + WarningReporter* reporter, + bool handle_inline) + : RootDIEHandler(handle_inline), + line_reader_(line_reader), cu_context_(new CUContext(file_context, reporter, ranges_handler)), child_context_(new DIEContext()), - has_source_line_info_(false) { -} + has_source_line_info_(false) {} DwarfCUToModule::~DwarfCUToModule() { } @@ -1183,14 +1191,15 @@ DIEHandler* DwarfCUToModule::FindChildHandler( enum DwarfTag tag) { switch (tag) { case DW_TAG_subprogram: - return new FuncHandler(cu_context_.get(), child_context_.get(), offset); + return new FuncHandler(cu_context_.get(), child_context_.get(), offset, + handle_inline); case DW_TAG_namespace: case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_module: return new NamedScopeHandler(cu_context_.get(), child_context_.get(), - offset); + offset, handle_inline); default: return NULL; } diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index 99dcd879..2873101a 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -258,7 +258,8 @@ class DwarfCUToModule: public RootDIEHandler { DwarfCUToModule(FileContext* file_context, LineToModuleHandler* line_reader, RangesHandler* ranges_handler, - WarningReporter* reporter); + WarningReporter* reporter, + bool handle_inline = false); ~DwarfCUToModule(); void ProcessAttributeSigned(enum DwarfAttribute attr, diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 92a260ba..ac53ea28 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -287,6 +287,7 @@ bool LoadDwarf(const string& dwarf_filename, const typename ElfClass::Ehdr* elf_header, const bool big_endian, bool handle_inter_cu_refs, + bool handle_inline, Module* module) { typedef typename ElfClass::Shdr Shdr; @@ -333,7 +334,7 @@ bool LoadDwarf(const string& dwarf_filename, // data that was found. DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset); DwarfCUToModule root_handler(&file_context, &line_to_module, - &ranges_handler, &reporter); + &ranges_handler, &reporter, handle_inline); // Make a Dwarf2Handler that drives the DIEHandler. google_breakpad::DIEDispatcher die_dispatcher(&root_handler); // Make a DWARF parser for the compilation unit at OFFSET. @@ -786,7 +787,8 @@ bool LoadSymbols(const string& obj_file, found_usable_info = true; info->LoadedSection(".debug_info"); if (!LoadDwarf(obj_file, elf_header, big_endian, - options.handle_inter_cu_refs, module)) { + options.handle_inter_cu_refs, + options.symbol_data & INLINES, module)) { fprintf(stderr, "%s: \".debug_info\" section found, but failed to load " "DWARF debugging information\n", obj_file.c_str()); } diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index 3592e4bb..6df32bc1 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -476,7 +476,8 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, DwarfCUToModule::WarningReporter reporter(selected_object_name_, offset); DwarfCUToModule root_handler(&file_context, &line_to_module, - &ranges_handler, &reporter); + &ranges_handler, &reporter, + symbol_data_ & INLINES); // Make a Dwarf2Handler that drives our DIEHandler. DIEDispatcher die_dispatcher(&root_handler); // Make a DWARF parser for the compilation unit at OFFSET. diff --git a/src/common/module.cc b/src/common/module.cc index eccd01f0..7dfd6a3e 100644 --- a/src/common/module.cc +++ b/src/common/module.cc @@ -303,8 +303,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { } if (symbol_data & SYMBOLS_AND_FILES) { - if (symbol_data & INLINES) - CreateInlineOrigins(); + CreateInlineOrigins(); AssignSourceIds(); // Write out files. @@ -318,13 +317,11 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { } } // Write out inline origins. - if (symbol_data & INLINES) { - for (InlineOrigin* origin : inline_origins_) { - stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID() - << " " << origin->name << "\n"; - if (!stream.good()) - return ReportError(); - } + for (InlineOrigin* origin : inline_origins_) { + stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID() + << " " << origin->name << "\n"; + if (!stream.good()) + return ReportError(); } // Write out functions and their inlines and lines. @@ -344,19 +341,17 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { return ReportError(); // Write out inlines. - if (symbol_data & INLINES) { - auto write_inline = [&](unique_ptr& in) { - stream << "INLINE "; - stream << in->inline_nest_level << " " << in->call_site_line << " " - << in->origin->id << hex; - for (const Range& r : in->ranges) - stream << " " << (r.address - load_address_) << " " << r.size; - stream << dec << "\n"; - }; - InlineDFS(func->inlines, write_inline); - if (!stream.good()) - return ReportError(); - } + auto write_inline = [&](unique_ptr& in) { + stream << "INLINE "; + stream << in->inline_nest_level << " " << in->call_site_line << " " + << in->origin->id << hex; + for (const Range& r : in->ranges) + stream << " " << (r.address - load_address_) << " " << r.size; + stream << dec << "\n"; + }; + InlineDFS(func->inlines, write_inline); + if (!stream.good()) + return ReportError(); while ((line_it != func->lines.end()) && (line_it->address >= range_it->address) &&