[Lldb-commits] [lldb] Report only loaded debug info in statistics dump (PR #81706)

via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 13 21:43:13 PST 2024


https://github.com/kusmour created https://github.com/llvm/llvm-project/pull/81706

Currently running `statistics dump` will trigger lldb to load debug info that's not yet loaded (eg. dwo files). Resulted in a delay in the command return, which, can be interrupting.

This patch also added a new option `--force` asking statistics to dump all possible debug info, which will force loading all debug info available.

>From 4ef72617dad197dc73305b9d231a065f264ed38a Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Mon, 5 Feb 2024 11:33:03 -0800
Subject: [PATCH 1/2] Only report total currently loaded debug info

---
 lldb/include/lldb/Symbol/SymbolFile.h              | 14 +++++++++++---
 lldb/include/lldb/Symbol/SymbolFileOnDemand.h      |  2 +-
 .../SymbolFile/Breakpad/SymbolFileBreakpad.cpp     |  2 +-
 .../SymbolFile/Breakpad/SymbolFileBreakpad.h       |  2 +-
 lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp |  5 +++--
 lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h   |  2 +-
 .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp   |  4 ++--
 .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h     | 14 +++++++++++++-
 .../SymbolFile/DWARF/SymbolFileDWARFDwo.cpp        |  2 +-
 .../Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h  |  2 +-
 .../SymbolFile/NativePDB/SymbolFileNativePDB.cpp   |  2 +-
 .../SymbolFile/NativePDB/SymbolFileNativePDB.h     |  2 +-
 lldb/source/Symbol/SymbolFile.cpp                  |  2 +-
 lldb/source/Symbol/SymbolFileOnDemand.cpp          |  4 ++--
 14 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index f356f7b789fa38..13a4d146d651ec 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -381,7 +381,8 @@ class SymbolFile : public PluginInterface {
 
   /// Metrics gathering functions
 
-  /// Return the size in bytes of all debug information in the symbol file.
+  /// Return the size in bytes of all loaded debug information or total possible
+  /// debug info 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
@@ -391,7 +392,14 @@ class SymbolFile : public PluginInterface {
   /// 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() = 0;
+  ///
+  /// \param load_if_needed
+  ///   If true, force loading any symbol files if they are not yet loaded and
+  ///   add to the total size
+  ///
+  /// \returns
+  ///   Total currently loaded debug info size in bytes
+  virtual uint64_t GetDebugInfoSize(bool load_if_needed = false) = 0;
 
   /// Return the time taken to parse the debug information.
   ///
@@ -534,7 +542,7 @@ class SymbolFileCommon : public SymbolFile {
 
   void Dump(Stream &s) override;
 
-  uint64_t GetDebugInfoSize() override;
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
 
   bool GetDebugInfoIndexWasLoadedFromCache() const override {
     return m_index_was_loaded_from_cache;
diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
index 4e3009941aa7d6..9b3512aa85cdd6 100644
--- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -178,7 +178,7 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
 
   void PreloadSymbols() override;
 
-  uint64_t GetDebugInfoSize() override;
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
   lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
   lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
 
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index b1f7397d6b0f00..ff0bba7bcab10c 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -918,7 +918,7 @@ void SymbolFileBreakpad::ParseUnwindData() {
   m_unwind_data->win.Sort();
 }
 
-uint64_t SymbolFileBreakpad::GetDebugInfoSize() {
+uint64_t SymbolFileBreakpad::GetDebugInfoSize(bool load_if_needed) {
   // Breakpad files are all debug info.
   return m_objfile_sp->GetByteSize();
 }
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 41e4e3b258014c..609ed6ffc9ff96 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -141,7 +141,7 @@ class SymbolFileBreakpad : public SymbolFileCommon {
 
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 
-  uint64_t GetDebugInfoSize() override;
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
 
 private:
   // A class representing a position in the breakpad file. Useful for
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 23e0b8a7f2c06b..4e822742780f8d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -896,8 +896,9 @@ void DWARFUnit::ComputeAbsolutePath() {
     m_file_spec->MakeAbsolute(GetCompilationDirectory());
 }
 
-SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() {
-  ExtractUnitDIEIfNeeded();
+SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile(bool load_if_needed) {
+  if (load_if_needed)
+    ExtractUnitDIEIfNeeded();
   if (m_dwo)
     return &llvm::cast<SymbolFileDWARFDwo>(m_dwo->GetSymbolFileDWARF());
   return nullptr;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 9f6d127056fa56..5a8a23e37738c6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -241,7 +241,7 @@ class DWARFUnit : public UserID {
   FileSpec GetFile(size_t file_idx);
   FileSpec::Style GetPathStyle();
 
-  SymbolFileDWARFDwo *GetDwoSymbolFile();
+  SymbolFileDWARFDwo *GetDwoSymbolFile(bool load_if_needed = false);
 
   die_iterator_range dies() {
     ExtractDIEsIfNeeded();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 781f5c5a436778..d8bbfa339ee4c0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2672,7 +2672,7 @@ static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match) {
   return any_context_updated;
 }
 
-uint64_t SymbolFileDWARF::GetDebugInfoSize() {
+uint64_t SymbolFileDWARF::GetDebugInfoSize(bool load_if_needed) {
   DWARFDebugInfo &info = DebugInfo();
   uint32_t num_comp_units = info.GetNumUnits();
 
@@ -2687,7 +2687,7 @@ uint64_t SymbolFileDWARF::GetDebugInfoSize() {
     if (cu == nullptr)
       continue;
 
-    SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
+    SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(load_if_needed);
     if (dwo)
       debug_info_size += dwo->GetDebugInfoSize();
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 01518b26ca669e..63114da66b4e37 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -186,7 +186,19 @@ class SymbolFileDWARF : public SymbolFileCommon {
   GetMangledNamesForFunction(const std::string &scope_qualified_name,
                              std::vector<ConstString> &mangled_names) override;
 
-  uint64_t GetDebugInfoSize() override;
+  /// Get total currently loaded debug info size or total possible debug info
+  /// size.
+  ///
+  /// For cases like .dwo files, the debug info = skeleton debug info +
+  /// all dwo debug info where .dwo files might not be loaded yet. Calling this
+  /// function by default will NOT force the loading of any .dwo files.
+  ///
+  /// \param load_if_needed
+  ///   If true, force loading any .dwo files associated and add to the size
+  ///
+  /// \return
+  ///     Returns total currently loaded debug info size
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
 
   void FindTypes(const lldb_private::TypeQuery &match,
                  lldb_private::TypeResults &results) override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index ea23b75c3d708d..950d43bdb51adb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -85,7 +85,7 @@ lldb::offset_t SymbolFileDWARFDwo::GetVendorDWARFOpcodeSize(
   return GetBaseSymbolFile().GetVendorDWARFOpcodeSize(data, data_offset, op);
 }
 
-uint64_t SymbolFileDWARFDwo::GetDebugInfoSize() {
+uint64_t SymbolFileDWARFDwo::GetDebugInfoSize(bool load_if_needed) {
   // Directly get debug info from current dwo object file's section list
   // instead of asking SymbolFileCommon::GetDebugInfo() which parses from
   // owning module which is wrong.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index d5f48f2a8ed4e2..daa591f460fa87 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -47,7 +47,7 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
                                           const lldb::offset_t data_offset,
                                           const uint8_t op) const override;
 
-  uint64_t GetDebugInfoSize() override;
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
 
   bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
                               lldb::offset_t &offset,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 745685a1b31d05..a434195614fcc9 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -2156,7 +2156,7 @@ SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
   return type_system_or_err;
 }
 
-uint64_t SymbolFileNativePDB::GetDebugInfoSize() {
+uint64_t SymbolFileNativePDB::GetDebugInfoSize(bool load_if_needed) {
   // PDB files are a separate file that contains all debug info.
   return m_index->pdb().getFileSize();
 }
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 82577771f355c8..588021f233904f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -77,7 +77,7 @@ class SymbolFileNativePDB : public SymbolFileCommon {
 
   void InitializeObject() override;
 
-  uint64_t GetDebugInfoSize() override;
+  uint64_t GetDebugInfoSize(bool load_if_needed = false) override;
 
   // Compile Unit function calls
 
diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index e318e2beb6547b..dba589c43a3cca 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -227,7 +227,7 @@ SymbolFileCommon::GetTypeSystemForLanguage(lldb::LanguageType language) {
   return type_system_or_err;
 }
 
-uint64_t SymbolFileCommon::GetDebugInfoSize() {
+uint64_t SymbolFileCommon::GetDebugInfoSize(bool load_if_needed) {
   if (!m_objfile_sp)
     return 0;
   ModuleSP module_sp(m_objfile_sp->GetModule());
diff --git a/lldb/source/Symbol/SymbolFileOnDemand.cpp b/lldb/source/Symbol/SymbolFileOnDemand.cpp
index bdb1951d51259d..65e6f19fc33b18 100644
--- a/lldb/source/Symbol/SymbolFileOnDemand.cpp
+++ b/lldb/source/Symbol/SymbolFileOnDemand.cpp
@@ -535,11 +535,11 @@ void SymbolFileOnDemand::PreloadSymbols() {
   return m_sym_file_impl->PreloadSymbols();
 }
 
-uint64_t SymbolFileOnDemand::GetDebugInfoSize() {
+uint64_t SymbolFileOnDemand::GetDebugInfoSize(bool load_if_needed) {
   // Always return the real debug info size.
   LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
            __FUNCTION__);
-  return m_sym_file_impl->GetDebugInfoSize();
+  return m_sym_file_impl->GetDebugInfoSize(load_if_needed);
 }
 
 StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoParseTime() {

>From b6df8630e43c278e143e29bf0c5bec550e6bc2fe Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Tue, 13 Feb 2024 13:34:41 -0800
Subject: [PATCH 2/2] Add statistics option to force loading debug info

---
 lldb/include/lldb/Target/Statistics.h       | 1 +
 lldb/source/Commands/CommandObjectStats.cpp | 3 +++
 lldb/source/Commands/Options.td             | 6 +++++-
 lldb/source/Target/Statistics.cpp           | 3 ++-
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h
index f838fa17f80c24..9f17834ab08f48 100644
--- a/lldb/include/lldb/Target/Statistics.h
+++ b/lldb/include/lldb/Target/Statistics.h
@@ -132,6 +132,7 @@ struct ConstStringStats {
 
 struct StatisticsOptions {
   bool summary_only = false;
+  bool force_loading = false;
 };
 
 /// A class that represents statistics for a since lldb_private::Target.
diff --git a/lldb/source/Commands/CommandObjectStats.cpp b/lldb/source/Commands/CommandObjectStats.cpp
index b23b7024c82176..7135d65b069a57 100644
--- a/lldb/source/Commands/CommandObjectStats.cpp
+++ b/lldb/source/Commands/CommandObjectStats.cpp
@@ -78,6 +78,9 @@ class CommandObjectStatsDump : public CommandObjectParsed {
       case 's':
         m_stats_options.summary_only = true;
         break;
+      case 'f':
+        m_stats_options.force_loading = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index dd732e35220287..fc607a5338fac7 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1419,6 +1419,10 @@ let Command = "statistics dump" in {
   def statistics_dump_all: Option<"all-targets", "a">, Group<1>,
     Desc<"Include statistics for all targets.">;
   def statistics_dump_summary: Option<"summary", "s">, Group<1>,
-    Desc<"Dump only high-level summary statistics."
+    Desc<"Dump only high-level summary statistics. "
          "Exclude targets, modules, breakpoints etc... details.">;
+  def statistics_dump_force: Option<"force", "f">, Group<1>,
+    Desc<"Dump the total possible debug info statistics. "
+    "Force loading the debug information if not yet loaded, and collect "
+    "statistics with those.">;
 }
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index ec0a4c84692dea..5035194f0d24e4 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -224,6 +224,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
     const lldb_private::StatisticsOptions &options) {
 
   const bool summary_only = options.summary_only;
+  const bool force_laoding = options.force_loading;
 
   json::Array json_targets;
   json::Array json_modules;
@@ -280,7 +281,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
         ++debug_index_saved;
       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();
+      module_stat.debug_info_size = sym_file->GetDebugInfoSize(force_laoding);
       module_stat.symtab_stripped = module->GetObjectFile()->IsStripped();
       if (module_stat.symtab_stripped)
         ++num_stripped_modules;



More information about the lldb-commits mailing list