Skip to content

[lldb] Avoid force loading symbol files in statistics collection #129593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 10, 2025

Conversation

dmpots
Copy link
Contributor

@dmpots dmpots commented Mar 3, 2025

This commit modifies the DebuggerStats::ReportStatistics implementation to avoid loading symbol files for unloaded symbols. We collect stats on debugger shutdown and without this change it can cause the debugger to hang for a long while on shutdown if they symbols were not previously loaded (e.g. settings set target.preload-symbols false).

The implementation is done by adding an optional parameter to Module::GetSymtab to control if the corresponding symbol file will be loaded in the same way that can control it for Module::GetSymbolFile.

This commit modifies the `DebuggerStats::ReportStatistics` implementation
to avoid loading symbol files for unloaded symbols. We collect stats
on debugger shutdown and without this change it can cause the debugger
to hang for a long while on shutdown if they symbols were not previously
loaded (e.g. `settings set target.preload-symbols false`).

The implementation is done by adding an optional parameter to
`Module::GetSymtab` to control if the corresponding symbol file will
be loaded in the same way that can control it for `Module::GetSymbolFile`.
@dmpots dmpots requested a review from JDevlieghere as a code owner March 3, 2025 21:33
@dmpots dmpots requested review from clayborg and removed request for JDevlieghere March 3, 2025 21:33
@llvmbot llvmbot added the lldb label Mar 3, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 3, 2025

@llvm/pr-subscribers-lldb

Author: David Peixotto (dmpots)

Changes

This commit modifies the DebuggerStats::ReportStatistics implementation to avoid loading symbol files for unloaded symbols. We collect stats on debugger shutdown and without this change it can cause the debugger to hang for a long while on shutdown if they symbols were not previously loaded (e.g. settings set target.preload-symbols false).

The implementation is done by adding an optional parameter to Module::GetSymtab to control if the corresponding symbol file will be loaded in the same way that can control it for Module::GetSymbolFile.


Full diff: https://github.com/llvm/llvm-project/pull/129593.diff

4 Files Affected:

  • (modified) lldb/include/lldb/Core/Module.h (+5-1)
  • (modified) lldb/source/Core/Module.cpp (+2-2)
  • (modified) lldb/source/Target/Statistics.cpp (+2-2)
  • (added) lldb/test/Shell/Commands/command-statistics-dump.test (+31)
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 90e0f4b6a3aac..9aa05ed3eb074 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -608,7 +608,11 @@ class Module : public std::enable_shared_from_this<Module>,
   virtual SymbolFile *GetSymbolFile(bool can_create = true,
                                     Stream *feedback_strm = nullptr);
 
-  Symtab *GetSymtab();
+  /// Get the module's symbol table
+  ///
+  /// If the symbol table has already been loaded, this function returns it.
+  /// Otherwise, it will only be loaded when can_create is true.
+  Symtab *GetSymtab(bool can_create = true);
 
   /// Get a reference to the UUID value contained in this object.
   ///
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 33668c5d20dde..d70f292abaea4 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1022,8 +1022,8 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
   return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
 }
 
-Symtab *Module::GetSymtab() {
-  if (SymbolFile *symbols = GetSymbolFile())
+Symtab *Module::GetSymtab(bool can_create) {
+  if (SymbolFile *symbols = GetSymbolFile(can_create))
     return symbols->GetSymtab();
   return nullptr;
 }
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index 8173d20457e21..b5d2e7bda1edf 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -316,7 +316,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
     ModuleStats module_stat;
     module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
     module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
-    Symtab *symtab = module->GetSymtab();
+    Symtab *symtab = module->GetSymtab(/*can_create=*/false);
     if (symtab) {
       module_stat.symtab_loaded_from_cache = symtab->GetWasLoadedFromCache();
       if (module_stat.symtab_loaded_from_cache)
@@ -325,7 +325,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
       if (module_stat.symtab_saved_to_cache)
         ++symtabs_saved;
     }
-    SymbolFile *sym_file = module->GetSymbolFile();
+    SymbolFile *sym_file = module->GetSymbolFile(/*can_create=*/false);
     if (sym_file) {
       if (!summary_only) {
         if (sym_file->GetObjectFile() != module->GetObjectFile())
diff --git a/lldb/test/Shell/Commands/command-statistics-dump.test b/lldb/test/Shell/Commands/command-statistics-dump.test
new file mode 100644
index 0000000000000..d490a0c374057
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-statistics-dump.test
@@ -0,0 +1,31 @@
+# RUN: %clang_host -g %S/Inputs/main.c -o %t-main.exe
+
+# When we enable symbol preload and dump stats there should be a non-zero
+# time for parsing symbol tables for the main module.
+# RUN: %lldb %t-main.exe \
+# RUN:       -O "settings set plugin.jit-loader.gdb.enable off" \
+# RUN:       -O "settings set target.preload-symbols true" \
+# RUN:       -o "statistics dump" \
+# RUN:       -o "q" \
+# RUN:       | FileCheck %s -check-prefixes=CHECK,PRELOAD_TRUE
+
+# Find the module stats for the main executable and make sure
+# we are looking at the symbol parse time for that module.
+# CHECK: "modules": [
+# CHECK: {
+# CHECK: "path": {{.*}}-main.exe
+# CHECK-NOT: }
+
+# PRELOAD_TRUE: "symbolTableParseTime":
+# PRELOAD_TRUE-SAME: {{[1-9]+}}
+
+# When we disable symbol preload and dump stats the symbol table
+# for main should not be parsed and have a time of 0.
+# RUN: %lldb %t-main.exe \
+# RUN:       -O "settings set plugin.jit-loader.gdb.enable off" \
+# RUN:       -O "settings set target.preload-symbols false" \
+# RUN:       -o "statistics dump" \
+# RUN:       -o "q" \
+# RUN:       | FileCheck %s -check-prefixes=CHECK,PRELOAD_FALSE
+
+# PRELOAD_FALSE: "symbolTableParseTime": 0,

@dmpots dmpots requested review from jeffreytan81 and Jlalond March 3, 2025 21:34
Copy link
Contributor

@Jlalond Jlalond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will let Jeffrey and Greg also chime in but this LGTM. My only concern would be testing the did not parse case by looking at a parse time of 0

@dmpots dmpots changed the title Avoid force loading symbol files in statistics collection [lldb] Avoid force loading symbol files in statistics collection Mar 4, 2025
Add a unit test to show that symbol tables are only
created on demand.
@dmpots
Copy link
Contributor Author

dmpots commented Mar 4, 2025

My only concern would be testing the did not parse case by looking at a parse time of 0

@Jlalond
I added a unit test to directly exercise the new overload and test that the symbol table is loaded on demand (when can_create is true).

Copy link
Contributor

@jeffreytan81 jeffreytan81 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good other than one comment.

Once it has been created then passing `can_create=false` should
have no effect.
@clayborg clayborg merged commit 1d1b20a into llvm:main Mar 10, 2025
10 checks passed
@dmpots dmpots deleted the stats-no-unloaded-symbols branch March 10, 2025 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants