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 <jperaza@chromium.org>
This commit is contained in:
Zequan Wu 2021-09-16 15:50:35 -07:00 committed by Joshua Peraza
parent 94c4208821
commit 30020c0d47
6 changed files with 54 additions and 43 deletions

View File

@ -258,10 +258,13 @@ class DIEHandler {
// A subclass of DIEHandler, with additional kludges for handling the // A subclass of DIEHandler, with additional kludges for handling the
// compilation unit's root die. // compilation unit's root die.
class RootDIEHandler: public DIEHandler { class RootDIEHandler : public DIEHandler {
public: public:
RootDIEHandler() { } bool handle_inline;
virtual ~RootDIEHandler() { }
explicit RootDIEHandler(bool handle_inline = false)
: handle_inline(handle_inline) {}
virtual ~RootDIEHandler() {}
// We pass the values reported via Dwarf2Handler::StartCompilationUnit // We pass the values reported via Dwarf2Handler::StartCompilationUnit
// to this member function, and skip the entire compilation unit if it // to this member function, and skip the entire compilation unit if it

View File

@ -766,11 +766,12 @@ void DwarfCUToModule::InlineHandler::Finish() {
class DwarfCUToModule::FuncHandler: public GenericDIEHandler { class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
public: public:
FuncHandler(CUContext* cu_context, DIEContext* parent_context, FuncHandler(CUContext* cu_context, DIEContext* parent_context,
uint64_t offset) uint64_t offset, bool handle_inline)
: GenericDIEHandler(cu_context, parent_context, offset), : GenericDIEHandler(cu_context, parent_context, offset),
low_pc_(0), high_pc_(0), high_pc_form_(DW_FORM_addr), low_pc_(0), high_pc_(0), high_pc_form_(DW_FORM_addr),
ranges_form_(DW_FORM_sec_offset), ranges_data_(0), 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, void ProcessAttributeUnsigned(enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
@ -794,6 +795,7 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
uint64_t decl_file_data_; uint64_t decl_file_data_;
bool inline_; bool inline_;
vector<unique_ptr<Module::Inline>> child_inlines_; vector<unique_ptr<Module::Inline>> child_inlines_;
bool handle_inline_;
}; };
void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned( void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
@ -844,8 +846,9 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler(
enum DwarfTag tag) { enum DwarfTag tag) {
switch (tag) { switch (tag) {
case DW_TAG_inlined_subroutine: case DW_TAG_inlined_subroutine:
return new InlineHandler(cu_context_, new DIEContext(), offset, 0, if (handle_inline_)
child_inlines_); return new InlineHandler(cu_context_, new DIEContext(), offset, 0,
child_inlines_);
default: default:
return NULL; return NULL;
} }
@ -949,7 +952,8 @@ void DwarfCUToModule::FuncHandler::Finish() {
// Only keep track of DW_TAG_subprogram which have the attributes we are // Only keep track of DW_TAG_subprogram which have the attributes we are
// interested. // interested.
if (!empty_range || inline_ || decl_file_data_ != UINT64_MAX) { if (handle_inline_ &&
(!empty_range || inline_ || decl_file_data_ != UINT64_MAX)) {
uint64_t offset = uint64_t offset =
specification_offset_ != 0 ? specification_offset_ : offset_; specification_offset_ != 0 ? specification_offset_ : offset_;
cu_context_->file_context->file_private_->inline_origin_map.SetReference( cu_context_->file_context->file_private_->inline_origin_map.SetReference(
@ -967,13 +971,14 @@ void DwarfCUToModule::FuncHandler::Finish() {
class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler {
public: public:
NamedScopeHandler(CUContext* cu_context, DIEContext* parent_context, NamedScopeHandler(CUContext* cu_context, DIEContext* parent_context,
uint64_t offset) uint64_t offset, bool handle_inline)
: GenericDIEHandler(cu_context, parent_context, offset) { } : GenericDIEHandler(cu_context, parent_context, offset) { }
bool EndAttributes(); bool EndAttributes();
DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag); DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag);
private: private:
DIEContext child_context_; // A context for our children. DIEContext child_context_; // A context for our children.
bool handle_inline_;
}; };
bool DwarfCUToModule::NamedScopeHandler::EndAttributes() { bool DwarfCUToModule::NamedScopeHandler::EndAttributes() {
@ -986,12 +991,14 @@ DIEHandler* DwarfCUToModule::NamedScopeHandler::FindChildHandler(
enum DwarfTag tag) { enum DwarfTag tag) {
switch (tag) { switch (tag) {
case DW_TAG_subprogram: 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_namespace:
case DW_TAG_class_type: case DW_TAG_class_type:
case DW_TAG_structure_type: case DW_TAG_structure_type:
case DW_TAG_union_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: default:
return NULL; return NULL;
} }
@ -1101,12 +1108,13 @@ void DwarfCUToModule::WarningReporter::MissingRanges() {
DwarfCUToModule::DwarfCUToModule(FileContext* file_context, DwarfCUToModule::DwarfCUToModule(FileContext* file_context,
LineToModuleHandler* line_reader, LineToModuleHandler* line_reader,
RangesHandler* ranges_handler, RangesHandler* ranges_handler,
WarningReporter* reporter) WarningReporter* reporter,
: line_reader_(line_reader), bool handle_inline)
: RootDIEHandler(handle_inline),
line_reader_(line_reader),
cu_context_(new CUContext(file_context, reporter, ranges_handler)), cu_context_(new CUContext(file_context, reporter, ranges_handler)),
child_context_(new DIEContext()), child_context_(new DIEContext()),
has_source_line_info_(false) { has_source_line_info_(false) {}
}
DwarfCUToModule::~DwarfCUToModule() { DwarfCUToModule::~DwarfCUToModule() {
} }
@ -1183,14 +1191,15 @@ DIEHandler* DwarfCUToModule::FindChildHandler(
enum DwarfTag tag) { enum DwarfTag tag) {
switch (tag) { switch (tag) {
case DW_TAG_subprogram: 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_namespace:
case DW_TAG_class_type: case DW_TAG_class_type:
case DW_TAG_structure_type: case DW_TAG_structure_type:
case DW_TAG_union_type: case DW_TAG_union_type:
case DW_TAG_module: case DW_TAG_module:
return new NamedScopeHandler(cu_context_.get(), child_context_.get(), return new NamedScopeHandler(cu_context_.get(), child_context_.get(),
offset); offset, handle_inline);
default: default:
return NULL; return NULL;
} }

View File

@ -258,7 +258,8 @@ class DwarfCUToModule: public RootDIEHandler {
DwarfCUToModule(FileContext* file_context, DwarfCUToModule(FileContext* file_context,
LineToModuleHandler* line_reader, LineToModuleHandler* line_reader,
RangesHandler* ranges_handler, RangesHandler* ranges_handler,
WarningReporter* reporter); WarningReporter* reporter,
bool handle_inline = false);
~DwarfCUToModule(); ~DwarfCUToModule();
void ProcessAttributeSigned(enum DwarfAttribute attr, void ProcessAttributeSigned(enum DwarfAttribute attr,

View File

@ -287,6 +287,7 @@ bool LoadDwarf(const string& dwarf_filename,
const typename ElfClass::Ehdr* elf_header, const typename ElfClass::Ehdr* elf_header,
const bool big_endian, const bool big_endian,
bool handle_inter_cu_refs, bool handle_inter_cu_refs,
bool handle_inline,
Module* module) { Module* module) {
typedef typename ElfClass::Shdr Shdr; typedef typename ElfClass::Shdr Shdr;
@ -333,7 +334,7 @@ bool LoadDwarf(const string& dwarf_filename,
// data that was found. // data that was found.
DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset); DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
DwarfCUToModule root_handler(&file_context, &line_to_module, DwarfCUToModule root_handler(&file_context, &line_to_module,
&ranges_handler, &reporter); &ranges_handler, &reporter, handle_inline);
// Make a Dwarf2Handler that drives the DIEHandler. // Make a Dwarf2Handler that drives the DIEHandler.
google_breakpad::DIEDispatcher die_dispatcher(&root_handler); google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET. // Make a DWARF parser for the compilation unit at OFFSET.
@ -786,7 +787,8 @@ bool LoadSymbols(const string& obj_file,
found_usable_info = true; found_usable_info = true;
info->LoadedSection(".debug_info"); info->LoadedSection(".debug_info");
if (!LoadDwarf<ElfClass>(obj_file, elf_header, big_endian, if (!LoadDwarf<ElfClass>(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 " fprintf(stderr, "%s: \".debug_info\" section found, but failed to load "
"DWARF debugging information\n", obj_file.c_str()); "DWARF debugging information\n", obj_file.c_str());
} }

View File

@ -476,7 +476,8 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module,
DwarfCUToModule::WarningReporter reporter(selected_object_name_, DwarfCUToModule::WarningReporter reporter(selected_object_name_,
offset); offset);
DwarfCUToModule root_handler(&file_context, &line_to_module, DwarfCUToModule root_handler(&file_context, &line_to_module,
&ranges_handler, &reporter); &ranges_handler, &reporter,
symbol_data_ & INLINES);
// Make a Dwarf2Handler that drives our DIEHandler. // Make a Dwarf2Handler that drives our DIEHandler.
DIEDispatcher die_dispatcher(&root_handler); DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET. // Make a DWARF parser for the compilation unit at OFFSET.

View File

@ -303,8 +303,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
} }
if (symbol_data & SYMBOLS_AND_FILES) { if (symbol_data & SYMBOLS_AND_FILES) {
if (symbol_data & INLINES) CreateInlineOrigins();
CreateInlineOrigins();
AssignSourceIds(); AssignSourceIds();
// Write out files. // Write out files.
@ -318,13 +317,11 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
} }
} }
// Write out inline origins. // Write out inline origins.
if (symbol_data & INLINES) { for (InlineOrigin* origin : inline_origins_) {
for (InlineOrigin* origin : inline_origins_) { stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID()
stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID() << " " << origin->name << "\n";
<< " " << origin->name << "\n"; if (!stream.good())
if (!stream.good()) return ReportError();
return ReportError();
}
} }
// Write out functions and their inlines and lines. // Write out functions and their inlines and lines.
@ -344,19 +341,17 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
return ReportError(); return ReportError();
// Write out inlines. // Write out inlines.
if (symbol_data & INLINES) { auto write_inline = [&](unique_ptr<Inline>& in) {
auto write_inline = [&](unique_ptr<Inline>& in) { stream << "INLINE ";
stream << "INLINE "; stream << in->inline_nest_level << " " << in->call_site_line << " "
stream << in->inline_nest_level << " " << in->call_site_line << " " << in->origin->id << hex;
<< in->origin->id << hex; for (const Range& r : in->ranges)
for (const Range& r : in->ranges) stream << " " << (r.address - load_address_) << " " << r.size;
stream << " " << (r.address - load_address_) << " " << r.size; stream << dec << "\n";
stream << dec << "\n"; };
}; InlineDFS(func->inlines, write_inline);
InlineDFS(func->inlines, write_inline); if (!stream.good())
if (!stream.good()) return ReportError();
return ReportError();
}
while ((line_it != func->lines.end()) && while ((line_it != func->lines.end()) &&
(line_it->address >= range_it->address) && (line_it->address >= range_it->address) &&