diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h --- a/lldb/include/lldb/Core/Section.h +++ b/lldb/include/lldb/Core/Section.h @@ -89,6 +89,12 @@ void Clear() { m_sections.clear(); } + /// Get the debug information size from all sections that contain debug + /// information. Symbol tables are not considered part of the debug + /// information for this call, just known sections that contain debug + /// information. + uint64_t GetDebugInfoSize() const; + protected: collection m_sections; }; @@ -236,6 +242,13 @@ void SetIsRelocated(bool b) { m_relocated = b; } + /// Returns true if this section contains debug information. Symbol tables + /// are not considered debug information since some symbols might contain + /// debug information (STABS, COFF) but not all symbols do, so to keep this + /// fast and simple only sections that contains only debug information should + /// return true. + bool ContainsOnlyDebugInfo() const; + protected: ObjectFile *m_obj_file; // The object file that data for this section should // be read from diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -19,6 +19,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" @@ -299,6 +300,38 @@ virtual void Dump(Stream &s); + /// Metrics gathering functions + + /// Return the size in bytes of all debug information in the symbol file. + /// + /// If the debug information is contained in sections of an ObjectFile, then + /// this call should add the size of all sections that contain debug + /// information. Symbols the symbol tables are not considered debug + /// information for this call to make it easy and quick for this number to be + /// calculated. If the symbol file is all debug information, the size of the + /// entire file should be returned. The default implementation of this + /// function will iterate over all sections in a module and add up their + /// debug info only section byte sizes. + virtual uint64_t GetDebugInfoSize(); + + /// Return the time taken to parse the debug information. + /// + /// \returns llvm::None if no information has been parsed or if there is + /// no computational cost to parsing the debug information. + virtual StatsDuration GetDebugInfoParseTime() { + return StatsDuration(0.0); + } + + /// Return the time it took to index the debug information in the object + /// file. + /// + /// \returns llvm::None if the file doesn't need to be indexed or if it + /// hasn't been indexed yet, or a valid duration if it has. + virtual StatsDuration GetDebugInfoIndexTime() { + return StatsDuration(0.0); + } + + protected: void AssertModuleLock(); virtual uint32_t CalculateNumCompileUnits() = 0; diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -81,6 +81,9 @@ std::string triple; double symtab_parse_time = 0.0; double symtab_index_time = 0.0; + double debug_parse_time = 0.0; + double debug_index_time = 0.0; + uint64_t debug_info_size = 0; }; /// A class that represents statistics for a since lldb_private::Target. diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -396,6 +396,76 @@ return 0; } +bool Section::ContainsOnlyDebugInfo() const { + switch (m_type) { + case eSectionTypeInvalid: + case eSectionTypeCode: + case eSectionTypeContainer: + case eSectionTypeData: + case eSectionTypeDataCString: + case eSectionTypeDataCStringPointers: + case eSectionTypeDataSymbolAddress: + case eSectionTypeData4: + case eSectionTypeData8: + case eSectionTypeData16: + case eSectionTypeDataPointers: + case eSectionTypeZeroFill: + case eSectionTypeDataObjCMessageRefs: + case eSectionTypeDataObjCCFStrings: + case eSectionTypeELFSymbolTable: + case eSectionTypeELFDynamicSymbols: + case eSectionTypeELFRelocationEntries: + case eSectionTypeELFDynamicLinkInfo: + case eSectionTypeEHFrame: + case eSectionTypeARMexidx: + case eSectionTypeARMextab: + case eSectionTypeCompactUnwind: + case eSectionTypeGoSymtab: + case eSectionTypeAbsoluteAddress: + case eSectionTypeOther: + return false; + + case eSectionTypeDebug: + case eSectionTypeDWARFDebugAbbrev: + case eSectionTypeDWARFDebugAbbrevDwo: + case eSectionTypeDWARFDebugAddr: + case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugCuIndex: + case eSectionTypeDWARFDebugTuIndex: + case eSectionTypeDWARFDebugFrame: + case eSectionTypeDWARFDebugInfo: + case eSectionTypeDWARFDebugInfoDwo: + case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: + case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugLocDwo: + case eSectionTypeDWARFDebugLocLists: + case eSectionTypeDWARFDebugLocListsDwo: + case eSectionTypeDWARFDebugMacInfo: + case eSectionTypeDWARFDebugMacro: + case eSectionTypeDWARFDebugPubNames: + case eSectionTypeDWARFDebugPubTypes: + case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: + case eSectionTypeDWARFDebugRngListsDwo: + case eSectionTypeDWARFDebugStr: + case eSectionTypeDWARFDebugStrDwo: + case eSectionTypeDWARFDebugStrOffsets: + case eSectionTypeDWARFDebugStrOffsetsDwo: + case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: + case eSectionTypeDWARFDebugNames: + case eSectionTypeDWARFAppleNames: + case eSectionTypeDWARFAppleTypes: + case eSectionTypeDWARFAppleNamespaces: + case eSectionTypeDWARFAppleObjC: + case eSectionTypeDWARFGNUDebugAltLink: + return true; + } + return false; +} + + #pragma mark SectionList SectionList &SectionList::operator=(const SectionList &rhs) { @@ -599,3 +669,15 @@ } return count; } + +uint64_t SectionList::GetDebugInfoSize() const { + uint64_t debug_info_size = 0; + for (const auto §ion : m_sections) { + const SectionList &sub_sections = section->GetChildren(); + if (sub_sections.GetSize() > 0) + debug_info_size += sub_sections.GetDebugInfoSize(); + else if (section->ContainsOnlyDebugInfo()) + debug_info_size += section->GetFileSize(); + } + return debug_info_size; +} \ No newline at end of file diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -150,6 +150,8 @@ return GetPluginNameStatic().GetStringRef(); } + uint64_t GetDebugInfoSize() override; + private: // A class representing a position in the breakpad file. Useful for // remembering the position so we can go back to it later and parse more data. diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -783,3 +783,9 @@ } m_unwind_data->win.Sort(); } + +uint64_t SymbolFileBreakpad::GetDebugInfoSize() { + // Breakpad files are all debug info. + return m_objfile_sp->GetByteSize(); +} + diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -13,6 +13,8 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/DWARFFormValue.h" +#include "lldb/Target/Statistics.h" + class DWARFDeclContext; class DWARFDIE; @@ -62,8 +64,11 @@ virtual void Dump(Stream &s) = 0; + StatsDuration GetIndexTime() { return m_index_time; } + protected: Module &m_module; + StatsDuration m_index_time{0.0}; /// Helper function implementing common logic for processing function dies. If /// the function given by "ref" matches search criteria given by diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -49,6 +49,7 @@ if (m_first_die) return; // Already parsed + ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractUnitDIENoDwoIfNeeded()", GetOffset()); @@ -196,6 +197,7 @@ void DWARFUnit::ExtractDIEsRWLocked() { llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex); + ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", GetOffset()); // Set the offset to that of the first DIE and calculate the start of the diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -30,6 +30,7 @@ SymbolFileDWARF &main_dwarf = *m_dwarf; m_dwarf = nullptr; + ElapsedTime elapsed(m_index_time); LLDB_SCOPED_TIMERF("%p", static_cast(&main_dwarf)); DWARFDebugInfo &main_info = main_dwarf.DebugInfo(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -24,6 +24,7 @@ #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/RangeMap.h" @@ -320,6 +321,16 @@ /// Same as GetLanguage() but reports all C++ versions as C++ (no version). static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit); + lldb_private::StatsDuration GetDebugInfoParseTime() override { + return m_parse_time; + } + lldb_private::StatsDuration GetDebugInfoIndexTime() override; + + lldb_private::StatsDuration &GetDebugInfoParseTimeRef() { + return m_parse_time; + } + + protected: typedef llvm::DenseMap DIEToTypePtr; @@ -550,6 +561,7 @@ /// 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; + lldb_private::StatsDuration m_parse_time{0.0}; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1009,6 +1009,7 @@ if (offset == DW_INVALID_OFFSET) return false; + ElapsedTime elapsed(m_parse_time); llvm::DWARFDebugLine::Prologue prologue; if (!ParseLLVMLineTablePrologue(m_context, prologue, offset, dwarf_cu.GetOffset())) @@ -1057,6 +1058,7 @@ "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " "the line table prologue"); }; + ElapsedTime elapsed(m_parse_time); llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx); if (error) { report(std::move(error)); @@ -1143,6 +1145,7 @@ if (offset == DW_INVALID_OFFSET) return false; + ElapsedTime elapsed(m_parse_time); llvm::DWARFDebugLine line; const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset()); @@ -1197,6 +1200,7 @@ if (iter != m_debug_macros_map.end()) return iter->second; + ElapsedTime elapsed(m_parse_time); const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData(); if (debug_macro_data.GetByteSize() == 0) return DebugMacrosSP(); @@ -4096,3 +4100,9 @@ lang = DW_LANG_C_plus_plus; return LanguageTypeFromDWARF(lang); } + +StatsDuration SymbolFileDWARF::GetDebugInfoIndexTime() { + if (m_index) + return m_index->GetIndexTime(); + return StatsDuration(0.0); +} \ No newline at end of file diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -144,6 +144,10 @@ return GetPluginNameStatic().GetStringRef(); } + uint64_t GetDebugInfoSize() override; + lldb_private::StatsDuration GetDebugInfoParseTime() override; + lldb_private::StatsDuration GetDebugInfoIndexTime() override; + protected: enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1434,3 +1434,54 @@ } return num_line_entries_added; } + +uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() { + uint64_t debug_info_size = 0; + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (!oso_objfile) + return false; // Keep iterating + ModuleSP module_sp = oso_objfile->GetModule(); + if (!module_sp) + return false; // Keep iterating + SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + debug_info_size += section_list->GetDebugInfoSize(); + return false; // Keep iterating + }); + return debug_info_size; +} + +StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() { + StatsDuration elapsed(0.0); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (oso_objfile) { + ModuleSP module_sp = oso_objfile->GetModule(); + if (module_sp) { + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (symfile) + elapsed += symfile->GetDebugInfoParseTime(); + } + } + return false; // Keep iterating + }); + return elapsed; +} + +StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() { + StatsDuration elapsed(0.0); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (oso_objfile) { + ModuleSP module_sp = oso_objfile->GetModule(); + if (module_sp) { + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (symfile) + elapsed += symfile->GetDebugInfoIndexTime(); + } + } + return false; // Keep iterating + }); + return elapsed; +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -75,6 +75,8 @@ void InitializeObject() override; + uint64_t GetDebugInfoSize() override; + // Compile Unit function calls void diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1566,3 +1566,9 @@ } return type_system_or_err; } + +uint64_t SymbolFileNativePDB::GetDebugInfoSize() { + // PDB files are a separate file that contains all debug info. + return m_index->pdb().getFileSize(); +} + diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -236,3 +236,15 @@ } SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; + +uint64_t SymbolFile::GetDebugInfoSize() { + if (!m_objfile_sp) + return 0; + ModuleSP module_sp(m_objfile_sp->GetModule()); + if (!module_sp) + return 0; + const SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + return section_list->GetDebugInfoSize(); + return 0; +} diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp --- a/lldb/source/Target/Statistics.cpp +++ b/lldb/source/Target/Statistics.cpp @@ -50,6 +50,9 @@ module.try_emplace("identifier", identifier); module.try_emplace("symbolTableParseTime", symtab_parse_time); module.try_emplace("symbolTableIndexTime", symtab_index_time); + module.try_emplace("debugInfoParseTime", debug_parse_time); + module.try_emplace("debugInfoIndexTime", debug_index_time); + module.try_emplace("debugInfoByteSize", (int64_t)debug_info_size); return module; } @@ -109,6 +112,9 @@ json::Array json_modules; double symtab_parse_time = 0.0; double symtab_index_time = 0.0; + double debug_parse_time = 0.0; + double debug_index_time = 0.0; + uint64_t debug_info_size = 0; if (target) { json_targets.emplace_back(target->ReportStatistics()); } else { @@ -119,18 +125,31 @@ std::lock_guard guard( Module::GetAllocationModuleCollectionMutex()); const size_t num_modules = Module::GetNumberAllocatedModules(); - ModuleSP module_sp; for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { Module *module = Module::GetAllocatedModuleAtIndex(image_idx); ModuleStats module_stat; module_stat.identifier = (intptr_t)module; module_stat.path = module->GetFileSpec().GetPath(); + if (ConstString object_name = module->GetObjectName()) { + module_stat.path.append(1, '('); + module_stat.path.append(object_name.GetStringRef().str()); + module_stat.path.append(1, ')'); + } module_stat.uuid = module->GetUUID().GetAsString(); module_stat.triple = module->GetArchitecture().GetTriple().str(); module_stat.symtab_parse_time = module->GetSymtabParseTime().count(); module_stat.symtab_index_time = module->GetSymtabIndexTime().count(); + SymbolFile *sym_file = module->GetSymbolFile(); + if (sym_file) { + module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); + module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); + module_stat.debug_info_size = sym_file->GetDebugInfoSize(); + } symtab_parse_time += module_stat.symtab_parse_time; symtab_index_time += module_stat.symtab_index_time; + debug_parse_time += module_stat.debug_parse_time; + debug_index_time += module_stat.debug_index_time; + debug_info_size += module_stat.debug_info_size; json_modules.emplace_back(module_stat.ToJSON()); } @@ -139,6 +158,9 @@ {"modules", std::move(json_modules)}, {"totalSymbolTableParseTime", symtab_parse_time}, {"totalSymbolTableIndexTime", symtab_index_time}, + {"totalDebugInfoParseTime", debug_parse_time}, + {"totalDebugInfoIndexTime", debug_index_time}, + {"totalDebugInfoByteSize", debug_info_size}, }; return std::move(global_stats); } diff --git a/lldb/test/API/commands/statistics/basic/TestStats.py b/lldb/test/API/commands/statistics/basic/TestStats.py --- a/lldb/test/API/commands/statistics/basic/TestStats.py +++ b/lldb/test/API/commands/statistics/basic/TestStats.py @@ -144,6 +144,9 @@ "moduleIdentifiers": [...], } ], + "totalDebugInfoByteSize": 182522234, + "totalDebugInfoIndexTime": 2.33343, + "totalDebugInfoParseTime": 8.2121400240000071, "totalSymbolTableParseTime": 0.123, "totalSymbolTableIndexTime": 0.234, } @@ -155,6 +158,9 @@ 'targets', 'totalSymbolTableParseTime', 'totalSymbolTableIndexTime', + 'totalDebugInfoByteSize', + 'totalDebugInfoIndexTime', + 'totalDebugInfoParseTime', ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) stats = debug_stats['targets'][0] @@ -198,6 +204,9 @@ }, } ], + "totalDebugInfoByteSize": 182522234, + "totalDebugInfoIndexTime": 2.33343, + "totalDebugInfoParseTime": 8.2121400240000071, "totalSymbolTableParseTime": 0.123, "totalSymbolTableIndexTime": 0.234, } @@ -212,6 +221,9 @@ 'targets', 'totalSymbolTableParseTime', 'totalSymbolTableIndexTime', + 'totalDebugInfoByteSize', + 'totalDebugInfoIndexTime', + 'totalDebugInfoParseTime', ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) stats = debug_stats['targets'][0] @@ -247,6 +259,9 @@ 'targets', 'totalSymbolTableParseTime', 'totalSymbolTableIndexTime', + 'totalDebugInfoParseTime', + 'totalDebugInfoIndexTime', + 'totalDebugInfoByteSize' ] self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) stats = debug_stats['targets'][0] @@ -256,6 +271,9 @@ self.verify_keys(stats, '"stats"', keys_exist, None) exe_module = self.find_module_in_metrics(exe, debug_stats) module_keys = [ + 'debugInfoByteSize', + 'debugInfoIndexTime', + 'debugInfoParseTime', 'identifier', 'path', 'symbolTableIndexTime',