[Lldb-commits] [lldb] Support statistics dump summary only mode (PR #80745)

via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 6 09:40:03 PST 2024


https://github.com/kusmour updated https://github.com/llvm/llvm-project/pull/80745

>From be36537cfc647735a823b685ab89ca68d1ae9803 Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Fri, 2 Feb 2024 15:42:01 -0800
Subject: [PATCH 1/4] Support statistics dump summary only mode

Summary:
Added a new --summary option to statistics dump command so that it is much light weight than the full version.
With this change, statistics dump --summary can now be included in lldb command line telemetry without slowing down lldb exiting.
---
 lldb/include/lldb/API/SBTarget.h              |   6 +-
 lldb/include/lldb/Target/Statistics.h         |   9 +-
 lldb/include/lldb/Target/Target.h             |   2 +-
 lldb/source/API/SBTarget.cpp                  |   9 +-
 lldb/source/Commands/CommandObjectStats.cpp   |   8 +-
 lldb/source/Commands/Options.td               |   3 +
 lldb/source/Target/Statistics.cpp             | 194 +++++++++++-------
 lldb/source/Target/Target.cpp                 |   4 +-
 .../stats_api/TestStatisticsAPI.py            |  15 ++
 9 files changed, 163 insertions(+), 87 deletions(-)

diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 83087623088c5..72b8997afd270 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -86,9 +86,13 @@ class LLDB_API SBTarget {
 
   /// Returns a dump of the collected statistics.
   ///
+  /// \param[in] summary_only
+  ///   If true, only report high level summary statistics without
+  ///   targets/modules/breakpoints etc.. details.
+  ///
   /// \return
   ///     A SBStructuredData with the statistics collected.
-  lldb::SBStructuredData GetStatistics();
+  lldb::SBStructuredData GetStatistics(bool summary_only = false);
 
   /// Return the platform object associated with the target.
   ///
diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h
index f672786f58f84..98658ba0cac31 100644
--- a/lldb/include/lldb/Target/Statistics.h
+++ b/lldb/include/lldb/Target/Statistics.h
@@ -133,7 +133,7 @@ struct ConstStringStats {
 /// A class that represents statistics for a since lldb_private::Target.
 class TargetStats {
 public:
-  llvm::json::Value ToJSON(Target &target);
+  llvm::json::Value ToJSON(Target &target, bool summary_only = false);
 
   void SetLaunchOrAttachTime();
   void SetFirstPrivateStopTime();
@@ -171,9 +171,14 @@ class DebuggerStats {
   ///   The single target to emit statistics for if non NULL, otherwise dump
   ///   statistics only for the specified target.
   ///
+  /// \param summary_only
+  ///   If true, only report high level summary statistics without
+  ///   targets/modules/breakpoints etc.. details.
+  ///
   /// \return
   ///     Returns a JSON value that contains all target metrics.
-  static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target);
+  static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target,
+                                            bool summary_only = false);
 
 protected:
   // Collecting stats can be set to true to collect stats that are expensive
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index c37682e2a0385..4bf6c123dc1dd 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -1599,7 +1599,7 @@ class Target : public std::enable_shared_from_this<Target>,
   ///
   /// \return
   ///     Returns a JSON value that contains all target metrics.
-  llvm::json::Value ReportStatistics();
+  llvm::json::Value ReportStatistics(bool summary_only = false);
 
   TargetStats &GetStatistics() { return m_stats; }
 
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 8e616afbcb4e8..615a00ceeaee1 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -197,7 +197,7 @@ SBDebugger SBTarget::GetDebugger() const {
   return debugger;
 }
 
-SBStructuredData SBTarget::GetStatistics() {
+SBStructuredData SBTarget::GetStatistics(bool summary_only) {
   LLDB_INSTRUMENT_VA(this);
 
   SBStructuredData data;
@@ -205,9 +205,10 @@ SBStructuredData SBTarget::GetStatistics() {
   if (!target_sp)
     return data;
   std::string json_str =
-      llvm::formatv("{0:2}",
-          DebuggerStats::ReportStatistics(target_sp->GetDebugger(),
-                                          target_sp.get())).str();
+      llvm::formatv(
+          "{0:2}", DebuggerStats::ReportStatistics(
+                       target_sp->GetDebugger(), target_sp.get(), summary_only))
+          .str();
   data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_str));
   return data;
 }
diff --git a/lldb/source/Commands/CommandObjectStats.cpp b/lldb/source/Commands/CommandObjectStats.cpp
index 262de0bda144a..781b90794dc37 100644
--- a/lldb/source/Commands/CommandObjectStats.cpp
+++ b/lldb/source/Commands/CommandObjectStats.cpp
@@ -75,6 +75,9 @@ class CommandObjectStatsDump : public CommandObjectParsed {
       case 'a':
         m_all_targets = true;
         break;
+      case 's':
+        m_summary_only = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -83,6 +86,7 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_all_targets = false;
+      m_summary_only = false;
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -90,6 +94,7 @@ class CommandObjectStatsDump : public CommandObjectParsed {
     }
 
     bool m_all_targets = false;
+    bool m_summary_only = false;
   };
 
 public:
@@ -109,7 +114,8 @@ class CommandObjectStatsDump : public CommandObjectParsed {
       target = m_exe_ctx.GetTargetPtr();
 
     result.AppendMessageWithFormatv(
-        "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target));
+        "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target,
+                                                 m_options.m_summary_only));
     result.SetStatus(eReturnStatusSuccessFinishResult);
   }
 
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index ed3167727bcd3..dba2e74a33a66 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1412,4 +1412,7 @@ let Command = "trace schema" in {
 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."
+         "Exclude targets, modules, breakpoints etc.. details.">;
 }
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index 4699710035b2d..eab7f807ae40e 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -12,6 +12,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/UnixSignals.h"
@@ -74,7 +75,7 @@ json::Value ModuleStats::ToJSON() const {
 
   if (!symfile_modules.empty()) {
     json::Array symfile_ids;
-    for (const auto symfile_id: symfile_modules)
+    for (const auto symfile_id : symfile_modules)
       symfile_ids.emplace_back(symfile_id);
     module.try_emplace("symbolFileModuleIdentifiers", std::move(symfile_ids));
   }
@@ -100,60 +101,91 @@ llvm::json::Value ConstStringStats::ToJSON() const {
   return obj;
 }
 
-json::Value TargetStats::ToJSON(Target &target) {
-  CollectStats(target);
+json::Value TargetStats::ToJSON(Target &target, bool summary_only) {
+  json::Object target_metrics_json;
+  ProcessSP process_sp = target.GetProcessSP();
+  if (!summary_only) {
+    CollectStats(target);
 
-  json::Array json_module_uuid_array;
-  for (auto module_identifier : m_module_identifiers)
-    json_module_uuid_array.emplace_back(module_identifier);
+    json::Array json_module_uuid_array;
+    for (auto module_identifier : m_module_identifiers)
+      json_module_uuid_array.emplace_back(module_identifier);
 
-  json::Object target_metrics_json{
-      {m_expr_eval.name, m_expr_eval.ToJSON()},
-      {m_frame_var.name, m_frame_var.ToJSON()},
-      {"moduleIdentifiers", std::move(json_module_uuid_array)}};
+    target_metrics_json.try_emplace(m_expr_eval.name, m_expr_eval.ToJSON());
+    target_metrics_json.try_emplace(m_frame_var.name, m_frame_var.ToJSON());
+    target_metrics_json.try_emplace("moduleIdentifiers",
+                                    std::move(json_module_uuid_array));
 
-  if (m_launch_or_attach_time && m_first_private_stop_time) {
-    double elapsed_time =
-        elapsed(*m_launch_or_attach_time, *m_first_private_stop_time);
-    target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time);
-  }
-  if (m_launch_or_attach_time && m_first_public_stop_time) {
-    double elapsed_time =
-        elapsed(*m_launch_or_attach_time, *m_first_public_stop_time);
-    target_metrics_json.try_emplace("firstStopTime", elapsed_time);
+    if (m_launch_or_attach_time && m_first_private_stop_time) {
+      double elapsed_time =
+          elapsed(*m_launch_or_attach_time, *m_first_private_stop_time);
+      target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time);
+    }
+    if (m_launch_or_attach_time && m_first_public_stop_time) {
+      double elapsed_time =
+          elapsed(*m_launch_or_attach_time, *m_first_public_stop_time);
+      target_metrics_json.try_emplace("firstStopTime", elapsed_time);
+    }
+    target_metrics_json.try_emplace("targetCreateTime",
+                                    m_create_time.get().count());
+
+    json::Array breakpoints_array;
+    double totalBreakpointResolveTime = 0.0;
+    // Rport both the normal breakpoint list and the internal breakpoint list.
+    for (int i = 0; i < 2; ++i) {
+      BreakpointList &breakpoints = target.GetBreakpointList(i == 1);
+      std::unique_lock<std::recursive_mutex> lock;
+      breakpoints.GetListMutex(lock);
+      size_t num_breakpoints = breakpoints.GetSize();
+      for (size_t i = 0; i < num_breakpoints; i++) {
+        Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
+        breakpoints_array.push_back(bp->GetStatistics());
+        totalBreakpointResolveTime += bp->GetResolveTime().count();
+      }
+    }
+    target_metrics_json.try_emplace("breakpoints",
+                                    std::move(breakpoints_array));
+    target_metrics_json.try_emplace("totalBreakpointResolveTime",
+                                    totalBreakpointResolveTime);
+
+    if (process_sp) {
+      UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals();
+      if (unix_signals_sp)
+        target_metrics_json.try_emplace(
+            "signals", unix_signals_sp->GetHitCountStatistics());
+    }
   }
-  target_metrics_json.try_emplace("targetCreateTime",
-                                  m_create_time.get().count());
-
-  json::Array breakpoints_array;
-  double totalBreakpointResolveTime = 0.0;
-  // Rport both the normal breakpoint list and the internal breakpoint list.
-  for (int i = 0; i < 2; ++i) {
-    BreakpointList &breakpoints = target.GetBreakpointList(i == 1);
+
+  // Counting "totalSharedLibraryEventHitCount" from breakpoints of kind
+  // "shared-library-event".
+  {
+    uint32_t shared_library_event_breakpoint_hit_count = 0;
+    // The "shared-library-event" is only found in the internal breakpoint list.
+    BreakpointList &breakpoints = target.GetBreakpointList(/* internal */ true);
     std::unique_lock<std::recursive_mutex> lock;
     breakpoints.GetListMutex(lock);
     size_t num_breakpoints = breakpoints.GetSize();
     for (size_t i = 0; i < num_breakpoints; i++) {
       Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
-      breakpoints_array.push_back(bp->GetStatistics());
-      totalBreakpointResolveTime += bp->GetResolveTime().count();
+      if (strcmp(bp->GetBreakpointKind(), "shared-library-event") == 0)
+        shared_library_event_breakpoint_hit_count += bp->GetHitCount();
     }
+
+    target_metrics_json.try_emplace("totalSharedLibraryEventHitCount",
+                                    shared_library_event_breakpoint_hit_count);
   }
 
-  ProcessSP process_sp = target.GetProcessSP();
   if (process_sp) {
-    UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals();
-    if (unix_signals_sp)
-      target_metrics_json.try_emplace("signals",
-                                      unix_signals_sp->GetHitCountStatistics());
     uint32_t stop_id = process_sp->GetStopID();
     target_metrics_json.try_emplace("stopCount", stop_id);
-  }
-  target_metrics_json.try_emplace("breakpoints", std::move(breakpoints_array));
-  target_metrics_json.try_emplace("totalBreakpointResolveTime",
-                                  totalBreakpointResolveTime);
-  target_metrics_json.try_emplace("sourceMapDeduceCount", m_source_map_deduce_count);
 
+    llvm::StringRef dyld_plugin_name;
+    if (process_sp->GetDynamicLoader())
+      dyld_plugin_name = process_sp->GetDynamicLoader()->GetPluginName();
+    target_metrics_json.try_emplace("dyldPluginName", dyld_plugin_name);
+  }
+  target_metrics_json.try_emplace("sourceMapDeduceCount",
+                                  m_source_map_deduce_count);
   return target_metrics_json;
 }
 
@@ -185,7 +217,8 @@ void TargetStats::IncreaseSourceMapDeduceCount() {
 bool DebuggerStats::g_collecting_stats = false;
 
 llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
-                                                  Target *target) {
+                                                  Target *target,
+                                                  bool summary_only) {
   json::Array json_targets;
   json::Array json_modules;
   double symtab_parse_time = 0.0;
@@ -197,12 +230,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
   uint32_t debug_index_loaded = 0;
   uint32_t debug_index_saved = 0;
   uint64_t debug_info_size = 0;
-  if (target) {
-    json_targets.emplace_back(target->ReportStatistics());
-  } else {
-    for (const auto &target : debugger.GetTargetList().Targets())
-      json_targets.emplace_back(target->ReportStatistics());
-  }
+
   std::vector<ModuleStats> modules;
   std::lock_guard<std::recursive_mutex> guard(
       Module::GetAllocationModuleCollectionMutex());
@@ -215,15 +243,6 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
   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().get().count();
     module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
     Symtab *symtab = module->GetSymtab();
@@ -237,13 +256,14 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
     }
     SymbolFile *sym_file = module->GetSymbolFile();
     if (sym_file) {
-
-      if (sym_file->GetObjectFile() != module->GetObjectFile())
-        module_stat.symfile_path =
-            sym_file->GetObjectFile()->GetFileSpec().GetPath();
-      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();
+      if (!summary_only) {
+        if (sym_file->GetObjectFile() != module->GetObjectFile())
+          module_stat.symfile_path =
+              sym_file->GetObjectFile()->GetFileSpec().GetPath();
+        ModuleList symbol_modules = sym_file->GetDebugInfoModules();
+        for (const auto &symbol_module : symbol_modules.Modules())
+          module_stat.symfile_modules.push_back((intptr_t)symbol_module.get());
+      }
       module_stat.debug_info_index_loaded_from_cache =
           sym_file->GetDebugInfoIndexWasLoadedFromCache();
       if (module_stat.debug_info_index_loaded_from_cache)
@@ -252,9 +272,9 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
           sym_file->GetDebugInfoIndexWasSavedToCache();
       if (module_stat.debug_info_index_saved_to_cache)
         ++debug_index_saved;
-      ModuleList symbol_modules = sym_file->GetDebugInfoModules();
-      for (const auto &symbol_module: symbol_modules.Modules())
-        module_stat.symfile_modules.push_back((intptr_t)symbol_module.get());
+      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.symtab_stripped = module->GetObjectFile()->IsStripped();
       if (module_stat.symtab_stripped)
         ++num_stripped_modules;
@@ -284,21 +304,21 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
     if (module_stat.debug_info_had_incomplete_types)
       ++num_modules_with_incomplete_types;
 
-    json_modules.emplace_back(module_stat.ToJSON());
+    if (!summary_only) {
+      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();
+      json_modules.emplace_back(module_stat.ToJSON());
+    }
   }
 
-  ConstStringStats const_string_stats;
-  json::Object json_memory{
-      {"strings", const_string_stats.ToJSON()},
-  };
-
-  json::Value cmd_stats = debugger.GetCommandInterpreter().GetStatistics();
-
   json::Object global_stats{
-      {"targets", std::move(json_targets)},
-      {"modules", std::move(json_modules)},
-      {"memory", std::move(json_memory)},
-      {"commands", std::move(cmd_stats)},
       {"totalSymbolTableParseTime", symtab_parse_time},
       {"totalSymbolTableIndexTime", symtab_index_time},
       {"totalSymbolTablesLoadedFromCache", symtabs_loaded},
@@ -316,5 +336,25 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
       {"totalDebugInfoEnabled", num_debug_info_enabled_modules},
       {"totalSymbolTableStripped", num_stripped_modules},
   };
+
+  if (target) {
+    json_targets.emplace_back(target->ReportStatistics(summary_only));
+  } else {
+    for (const auto &target : debugger.GetTargetList().Targets())
+      json_targets.emplace_back(target->ReportStatistics(summary_only));
+  }
+  global_stats.try_emplace("targets", std::move(json_targets));
+
+  if (!summary_only) {
+    ConstStringStats const_string_stats;
+    json::Object json_memory{
+        {"strings", const_string_stats.ToJSON()},
+    };
+    json::Value cmd_stats = debugger.GetCommandInterpreter().GetStatistics();
+    global_stats.try_emplace("modules", std::move(json_modules));
+    global_stats.try_emplace("memory", std::move(json_memory));
+    global_stats.try_emplace("commands", std::move(cmd_stats));
+  }
+
   return std::move(global_stats);
 }
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index e969340fdf1eb..e36c03267853f 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4962,4 +4962,6 @@ std::recursive_mutex &Target::GetAPIMutex() {
 }
 
 /// Get metrics associated with this target in JSON format.
-llvm::json::Value Target::ReportStatistics() { return m_stats.ToJSON(*this); }
+llvm::json::Value Target::ReportStatistics(bool summary_only) {
+  return m_stats.ToJSON(*this, summary_only);
+}
diff --git a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
index fe55922fe4c31..00a7ccb4b56ab 100644
--- a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
+++ b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
@@ -74,6 +74,21 @@ def test_stats_api(self):
             'Make sure the "failures" key in in "frameVariable" dictionary"',
         )
 
+        # Test statistics summary.
+        stats_summary = target.GetStatistics(True)
+        stream_summary = lldb.SBStream()
+        res = stats_summary.GetAsJSON(stream_summary)
+        debug_stats_summary = json.loads(stream_summary.GetData())
+        self.assertNotIn("modules", debug_stats_summary)
+        self.assertNotIn("memory", debug_stats_summary)
+        self.assertNotIn("commands", debug_stats_summary)
+
+        # Summary values should be the same as in full statistics.
+        for key, value in debug_stats_summary.items():
+            self.assertIn(key, debug_stats)
+            if key != "targets":
+                self.assertEqual(debug_stats[key], value)
+
     def test_command_stats_api(self):
         """
         Test GetCommandInterpreter::GetStatistics() API.

>From b9267282f62c60e20435b20b178feec9e8569817 Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Mon, 5 Feb 2024 15:33:16 -0800
Subject: [PATCH 2/4] address nit comments

---
 lldb/source/Commands/Options.td   | 4 ++--
 lldb/source/Target/Statistics.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index dba2e74a33a66..a87f457105aac 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1413,6 +1413,6 @@ 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."
-         "Exclude targets, modules, breakpoints etc.. details.">;
+    Desc<"Dump only high-level summary statistics."
+         "Exclude targets, modules, breakpoints etc... details.">;
 }
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index eab7f807ae40e..26a6b26e2e8c9 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -75,7 +75,7 @@ json::Value ModuleStats::ToJSON() const {
 
   if (!symfile_modules.empty()) {
     json::Array symfile_ids;
-    for (const auto symfile_id : symfile_modules)
+    for (const auto symfile_id: symfile_modules)
       symfile_ids.emplace_back(symfile_id);
     module.try_emplace("symbolFileModuleIdentifiers", std::move(symfile_ids));
   }
@@ -131,7 +131,7 @@ json::Value TargetStats::ToJSON(Target &target, bool summary_only) {
 
     json::Array breakpoints_array;
     double totalBreakpointResolveTime = 0.0;
-    // Rport both the normal breakpoint list and the internal breakpoint list.
+    // Report both the normal breakpoint list and the internal breakpoint list.
     for (int i = 0; i < 2; ++i) {
       BreakpointList &breakpoints = target.GetBreakpointList(i == 1);
       std::unique_lock<std::recursive_mutex> lock;

>From e5a14bb11a3196ea13877d27e9ae1fb5247f2a25 Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Mon, 5 Feb 2024 20:18:23 -0800
Subject: [PATCH 3/4] Create SBStatisticsOptions API

Summary:
We can't take away or change a previously available public API function.
To avoid future changes, intruduce an option class that we can extend without modifying existing APIs.
---
 lldb/bindings/headers.swig                    |  1 +
 .../interface/SBStatisticsOptionsDocStrings.i |  8 +++
 lldb/bindings/interfaces.swig                 |  2 +
 lldb/include/lldb/API/LLDB.h                  |  1 +
 lldb/include/lldb/API/SBDefines.h             |  1 +
 lldb/include/lldb/API/SBStatisticsOptions.h   | 36 +++++++++++++
 lldb/include/lldb/API/SBTarget.h              | 14 +++--
 lldb/include/lldb/Target/Statistics.h         | 12 +++--
 lldb/include/lldb/Target/Target.h             |  2 +-
 lldb/include/lldb/lldb-forward.h              |  1 +
 lldb/source/API/CMakeLists.txt                |  1 +
 lldb/source/API/SBStatisticsOptions.cpp       | 51 +++++++++++++++++++
 lldb/source/API/SBTarget.cpp                  | 10 +++-
 lldb/source/Commands/CommandObjectStats.cpp   | 15 ++++--
 lldb/source/Target/Statistics.cpp             | 18 ++++---
 lldb/source/Target/Target.cpp                 |  4 +-
 .../stats_api/TestStatisticsAPI.py            |  8 ++-
 17 files changed, 161 insertions(+), 24 deletions(-)
 create mode 100644 lldb/bindings/interface/SBStatisticsOptionsDocStrings.i
 create mode 100644 lldb/include/lldb/API/SBStatisticsOptions.h
 create mode 100644 lldb/source/API/SBStatisticsOptions.cpp

diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig
index 408db90b925f1..e8d0cda288141 100644
--- a/lldb/bindings/headers.swig
+++ b/lldb/bindings/headers.swig
@@ -54,6 +54,7 @@
 #include "lldb/API/SBScriptObject.h"
 #include "lldb/API/SBSection.h"
 #include "lldb/API/SBSourceManager.h"
+#include "lldb/API/SBStatisticsOptions.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStringList.h"
 #include "lldb/API/SBStructuredData.h"
diff --git a/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i b/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i
new file mode 100644
index 0000000000000..f72cf84319e19
--- /dev/null
+++ b/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i
@@ -0,0 +1,8 @@
+%feature("docstring",
+"A container for options to use when dumping statistics."
+) lldb::SBStatisticsOptions;
+
+%feature("docstring", "Sets whether the statistics should only dump a summary."
+) lldb::SBStatisticsOptions::SetSummaryOnly;
+%feature("docstring", "Gets whether the statistics only dump a summary."
+) lldb::SBStatisticsOptions::GetSummaryOnly;
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 9ca479218f621..a31a0b4af1eb6 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -56,6 +56,7 @@
 %include "./interface/SBReproducerDocstrings.i"
 %include "./interface/SBSectionDocstrings.i"
 %include "./interface/SBSourceManagerDocstrings.i"
+%include "./interface/SBStatisticsOptionsDocstrings.i"
 %include "./interface/SBStreamDocstrings.i"
 %include "./interface/SBStringListDocstrings.i"
 %include "./interface/SBStructuredDataDocstrings.i"
@@ -131,6 +132,7 @@
 %include "lldb/API/SBScriptObject.h"
 %include "lldb/API/SBSection.h"
 %include "lldb/API/SBSourceManager.h"
+%include "lldb/API/SBStatisticsOptions.h"
 %include "lldb/API/SBStream.h"
 %include "lldb/API/SBStringList.h"
 %include "lldb/API/SBStructuredData.h"
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index f5f1b87a046c2..c83eb92fcfb30 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -56,6 +56,7 @@
 #include "lldb/API/SBReproducer.h"
 #include "lldb/API/SBSection.h"
 #include "lldb/API/SBSourceManager.h"
+#include "lldb/API/SBStatisticsOptions.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStringList.h"
 #include "lldb/API/SBStructuredData.h"
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index 92d823fa1dfe2..1181920677b46 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -99,6 +99,7 @@ class LLDB_API SBReproducer;
 class LLDB_API SBScriptObject;
 class LLDB_API SBSection;
 class LLDB_API SBSourceManager;
+class LLDB_API SBStatisticsOptions;
 class LLDB_API SBStream;
 class LLDB_API SBStringList;
 class LLDB_API SBStructuredData;
diff --git a/lldb/include/lldb/API/SBStatisticsOptions.h b/lldb/include/lldb/API/SBStatisticsOptions.h
new file mode 100644
index 0000000000000..bcd99aebebf73
--- /dev/null
+++ b/lldb/include/lldb/API/SBStatisticsOptions.h
@@ -0,0 +1,36 @@
+//===-- SBStatisticsOptions.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_API_SBSTATISTICSOPTIONS_H
+#define LLDB_API_SBSTATISTICSOPTIONS_H
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+/// This class handles the verbosity when dumping statistics 
+class LLDB_API SBStatisticsOptions {
+public:
+  SBStatisticsOptions();
+  SBStatisticsOptions(const lldb::SBStatisticsOptions &rhs);
+  ~SBStatisticsOptions();
+
+  const SBStatisticsOptions &operator=(const lldb::SBStatisticsOptions &rhs);
+
+  void SetSummaryOnly(bool b);
+  bool GetSummaryOnly();
+
+protected:
+  friend class SBTarget;
+  const lldb_private::StatisticsOptions &ref() const;
+
+private:
+  std::unique_ptr<lldb_private::StatisticsOptions> m_opaque_up;
+};
+} // namespace lldb
+#endif // LLDB_API_SBSTATISTICSOPTIONS_H
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 72b8997afd270..f7bdd3093d202 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -17,6 +17,7 @@
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBFileSpecList.h"
 #include "lldb/API/SBLaunchInfo.h"
+#include "lldb/API/SBStatisticsOptions.h"
 #include "lldb/API/SBSymbolContextList.h"
 #include "lldb/API/SBType.h"
 #include "lldb/API/SBValue.h"
@@ -86,13 +87,18 @@ class LLDB_API SBTarget {
 
   /// Returns a dump of the collected statistics.
   ///
-  /// \param[in] summary_only
-  ///   If true, only report high level summary statistics without
-  ///   targets/modules/breakpoints etc.. details.
+  /// \return
+  ///     A SBStructuredData with the statistics collected.
+  lldb::SBStructuredData GetStatistics();
+
+  /// Returns a dump of the collected statistics.
+  ///
+  /// \param[in] options
+  ///   An objects object that contains all options for the statistics dumping.
   ///
   /// \return
   ///     A SBStructuredData with the statistics collected.
-  lldb::SBStructuredData GetStatistics(bool summary_only = false);
+  lldb::SBStructuredData GetStatistics(SBStatisticsOptions options);
 
   /// Return the platform object associated with the target.
   ///
diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h
index 98658ba0cac31..cc89dcf902aa6 100644
--- a/lldb/include/lldb/Target/Statistics.h
+++ b/lldb/include/lldb/Target/Statistics.h
@@ -130,10 +130,15 @@ struct ConstStringStats {
   ConstString::MemoryStats stats = ConstString::GetMemoryStats();
 };
 
+struct StatisticsOptions {
+  bool summary_only = false;
+};
+
 /// A class that represents statistics for a since lldb_private::Target.
 class TargetStats {
 public:
-  llvm::json::Value ToJSON(Target &target, bool summary_only = false);
+  llvm::json::Value ToJSON(Target &target,
+                     const lldb_private::StatisticsOptions &options);
 
   void SetLaunchOrAttachTime();
   void SetFirstPrivateStopTime();
@@ -177,8 +182,9 @@ class DebuggerStats {
   ///
   /// \return
   ///     Returns a JSON value that contains all target metrics.
-  static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target,
-                                            bool summary_only = false);
+  static llvm::json::Value
+  ReportStatistics(Debugger &debugger, Target *target,
+                   const lldb_private::StatisticsOptions &options);
 
 protected:
   // Collecting stats can be set to true to collect stats that are expensive
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 4bf6c123dc1dd..0f3d358198c6a 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -1599,7 +1599,7 @@ class Target : public std::enable_shared_from_this<Target>,
   ///
   /// \return
   ///     Returns a JSON value that contains all target metrics.
-  llvm::json::Value ReportStatistics(bool summary_only = false);
+  llvm::json::Value ReportStatistics(const lldb_private::StatisticsOptions &options);
 
   TargetStats &GetStatistics() { return m_stats; }
 
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index d89ad21512215..10ba921b9dac8 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -298,6 +298,7 @@ struct CompilerContext;
 struct LineEntry;
 struct PropertyDefinition;
 struct ScriptSummaryFormat;
+struct StatisticsOptions;
 struct StringSummaryFormat;
 template <unsigned N> class StreamBuffer;
 
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index 7d478ecc7f599..57cc44f764675 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -69,6 +69,7 @@ add_lldb_library(liblldb SHARED ${option_framework}
   SBScriptObject.cpp
   SBSection.cpp
   SBSourceManager.cpp
+  SBStatisticsOptions.cpp
   SBStream.cpp
   SBStringList.cpp
   SBStructuredData.cpp
diff --git a/lldb/source/API/SBStatisticsOptions.cpp b/lldb/source/API/SBStatisticsOptions.cpp
new file mode 100644
index 0000000000000..8e8f8bd75c994
--- /dev/null
+++ b/lldb/source/API/SBStatisticsOptions.cpp
@@ -0,0 +1,51 @@
+//===-- SBStatisticsOptions.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBStatisticsOptions.h"
+#include "lldb/Target/Statistics.h"
+#include "lldb/Utility/Instrumentation.h"
+
+#include "Utils.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBStatisticsOptions::SBStatisticsOptions()
+    : m_opaque_up(new StatisticsOptions()) {
+  LLDB_INSTRUMENT_VA(this);
+  m_opaque_up->summary_only = false;
+}
+
+SBStatisticsOptions::SBStatisticsOptions(const SBStatisticsOptions &rhs) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  m_opaque_up = clone(rhs.m_opaque_up);
+}
+
+SBStatisticsOptions::~SBStatisticsOptions() = default;
+
+const SBStatisticsOptions &
+SBStatisticsOptions::operator=(const SBStatisticsOptions &rhs) {
+  LLDB_INSTRUMENT_VA(this, rhs);
+
+  if (this != &rhs)
+    m_opaque_up = clone(rhs.m_opaque_up);
+  return *this;
+}
+
+void SBStatisticsOptions::SetSummaryOnly(bool b) {
+  m_opaque_up->summary_only = b;
+}
+
+bool SBStatisticsOptions::GetSummaryOnly() {
+  return m_opaque_up->summary_only;
+}
+
+const lldb_private::StatisticsOptions &SBStatisticsOptions::ref() const {
+  return *m_opaque_up;
+}
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 615a00ceeaee1..6779a6900274b 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -197,7 +197,13 @@ SBDebugger SBTarget::GetDebugger() const {
   return debugger;
 }
 
-SBStructuredData SBTarget::GetStatistics(bool summary_only) {
+SBStructuredData SBTarget::GetStatistics() {
+   LLDB_INSTRUMENT_VA(this);
+  SBStatisticsOptions options;
+  return GetStatistics(options);
+}
+
+SBStructuredData SBTarget::GetStatistics(SBStatisticsOptions options) {
   LLDB_INSTRUMENT_VA(this);
 
   SBStructuredData data;
@@ -207,7 +213,7 @@ SBStructuredData SBTarget::GetStatistics(bool summary_only) {
   std::string json_str =
       llvm::formatv(
           "{0:2}", DebuggerStats::ReportStatistics(
-                       target_sp->GetDebugger(), target_sp.get(), summary_only))
+                       target_sp->GetDebugger(), target_sp.get(), options.ref()))
           .str();
   data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_str));
   return data;
diff --git a/lldb/source/Commands/CommandObjectStats.cpp b/lldb/source/Commands/CommandObjectStats.cpp
index 781b90794dc37..d1a4e1adcb159 100644
--- a/lldb/source/Commands/CommandObjectStats.cpp
+++ b/lldb/source/Commands/CommandObjectStats.cpp
@@ -76,7 +76,7 @@ class CommandObjectStatsDump : public CommandObjectParsed {
         m_all_targets = true;
         break;
       case 's':
-        m_summary_only = true;
+        m_stats_options.summary_only = true;
         break;
       default:
         llvm_unreachable("Unimplemented option");
@@ -86,15 +86,20 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_all_targets = false;
-      m_summary_only = false;
+      m_stats_options = StatisticsOptions();
+
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
       return llvm::ArrayRef(g_statistics_dump_options);
     }
 
+    StatisticsOptions GetStatisticsOptions() {
+      return m_stats_options;
+    }
+
     bool m_all_targets = false;
-    bool m_summary_only = false;
+    StatisticsOptions m_stats_options = StatisticsOptions();
   };
 
 public:
@@ -114,8 +119,8 @@ class CommandObjectStatsDump : public CommandObjectParsed {
       target = m_exe_ctx.GetTargetPtr();
 
     result.AppendMessageWithFormatv(
-        "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target,
-                                                 m_options.m_summary_only));
+        "{0:2}", DebuggerStats::ReportStatistics(
+                     GetDebugger(), target, m_options.GetStatisticsOptions()));
     result.SetStatus(eReturnStatusSuccessFinishResult);
   }
 
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index 26a6b26e2e8c9..4f84caf5cbbe0 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -101,9 +101,12 @@ llvm::json::Value ConstStringStats::ToJSON() const {
   return obj;
 }
 
-json::Value TargetStats::ToJSON(Target &target, bool summary_only) {
+json::Value
+TargetStats::ToJSON(Target &target,
+                    const lldb_private::StatisticsOptions &options) {
   json::Object target_metrics_json;
   ProcessSP process_sp = target.GetProcessSP();
+  bool summary_only = options.summary_only;
   if (!summary_only) {
     CollectStats(target);
 
@@ -216,9 +219,12 @@ void TargetStats::IncreaseSourceMapDeduceCount() {
 
 bool DebuggerStats::g_collecting_stats = false;
 
-llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
-                                                  Target *target,
-                                                  bool summary_only) {
+llvm::json::Value DebuggerStats::ReportStatistics(
+    Debugger &debugger, Target *target,
+    const lldb_private::StatisticsOptions &options) {
+
+  bool summary_only = options.summary_only;
+
   json::Array json_targets;
   json::Array json_modules;
   double symtab_parse_time = 0.0;
@@ -338,10 +344,10 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
   };
 
   if (target) {
-    json_targets.emplace_back(target->ReportStatistics(summary_only));
+    json_targets.emplace_back(target->ReportStatistics(options));
   } else {
     for (const auto &target : debugger.GetTargetList().Targets())
-      json_targets.emplace_back(target->ReportStatistics(summary_only));
+      json_targets.emplace_back(target->ReportStatistics(options));
   }
   global_stats.try_emplace("targets", std::move(json_targets));
 
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index e36c03267853f..2fe6686cac7e3 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4962,6 +4962,6 @@ std::recursive_mutex &Target::GetAPIMutex() {
 }
 
 /// Get metrics associated with this target in JSON format.
-llvm::json::Value Target::ReportStatistics(bool summary_only) {
-  return m_stats.ToJSON(*this, summary_only);
+llvm::json::Value Target::ReportStatistics(const lldb_private::StatisticsOptions &options) {
+  return m_stats.ToJSON(*this, options);
 }
diff --git a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
index 00a7ccb4b56ab..692cd662c393a 100644
--- a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
+++ b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py
@@ -75,7 +75,9 @@ def test_stats_api(self):
         )
 
         # Test statistics summary.
-        stats_summary = target.GetStatistics(True)
+        stats_options = lldb.SBStatisticsOptions()
+        stats_options.SetSummaryOnly(True)
+        stats_summary = target.GetStatistics(stats_options)
         stream_summary = lldb.SBStream()
         res = stats_summary.GetAsJSON(stream_summary)
         debug_stats_summary = json.loads(stream_summary.GetData())
@@ -84,9 +86,13 @@ def test_stats_api(self):
         self.assertNotIn("commands", debug_stats_summary)
 
         # Summary values should be the same as in full statistics.
+        print(debug_stats)
+        print("\n")
+        print(debug_stats_summary)
         for key, value in debug_stats_summary.items():
             self.assertIn(key, debug_stats)
             if key != "targets":
+                print(f"\nkey: {key}, value: {value}\n")
                 self.assertEqual(debug_stats[key], value)
 
     def test_command_stats_api(self):

>From 600ae3dd8e8fdf9f6dcb4265f473bf01081f4d0f 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 4/4] Only report total currently loaded debug info

---
 lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp       | 5 +++--
 lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h         | 2 +-
 lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +-
 lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h   | 4 ++++
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 23e0b8a7f2c06..4e822742780f8 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 9f6d127056fa5..815738d8a1933 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 = true);
 
   die_iterator_range dies() {
     ExtractDIEsIfNeeded();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 781f5c5a43677..0918a77f83cf7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2687,7 +2687,7 @@ uint64_t SymbolFileDWARF::GetDebugInfoSize() {
     if (cu == nullptr)
       continue;
 
-    SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile();
+    SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(false);
     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 60baf694b463e..b80699322688f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -186,6 +186,10 @@ class SymbolFileDWARF : public SymbolFileCommon {
   GetMangledNamesForFunction(const std::string &scope_qualified_name,
                              std::vector<ConstString> &mangled_names) override;
 
+  /// Return total currently loaded debug info.
+  /// 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
+  /// will not force the loading of any .dwo files.
   uint64_t GetDebugInfoSize() override;
 
   void FindTypes(const lldb_private::TypeQuery &match,



More information about the lldb-commits mailing list