[Lldb-commits] [lldb] c2f9454 - [lldb] Add SBModule::GarbageCollectAllocatedModules and clear modules after each test run

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Mon Aug 17 02:00:49 PDT 2020


Author: Raphael Isemann
Date: 2020-08-17T11:00:19+02:00
New Revision: c2f9454a16e45e1df09d8ebed6dadbc0da264442

URL: https://github.com/llvm/llvm-project/commit/c2f9454a16e45e1df09d8ebed6dadbc0da264442
DIFF: https://github.com/llvm/llvm-project/commit/c2f9454a16e45e1df09d8ebed6dadbc0da264442.diff

LOG: [lldb] Add SBModule::GarbageCollectAllocatedModules and clear modules after each test run

Right now the only places in the SB API where lldb:: ModuleSP instances are
destroyed are in SBDebugger::MemoryPressureDetected (where it's just attempted
but not guaranteed) and in SBDebugger::DeleteTarget (which will be removed in
D83933). Tests that directly create an lldb::ModuleSP and never create a target
therefore currently leak lldb::Module instances. This triggers the sanity checks
in lldbtest that make sure that the global module list is empty after a test.

This patch adds SBModule::GarbageCollectAllocatedModules as an explicit way to
clean orphaned lldb::ModuleSP instances. Also we now start calling this method
at the end of each test run and move the sanity check behind that call to make
this work. This way even tests that don't create targets can pass the sanity
check.

This fixes TestUnicodeSymbols.py when D83865 is applied (which makes that the
sanity checks actually fail the test).

Reviewed By: JDevlieghere

Differential Revision: https://reviews.llvm.org/D83876

Added: 
    

Modified: 
    lldb/bindings/interface/SBModule.i
    lldb/include/lldb/API/SBModule.h
    lldb/packages/Python/lldbsuite/test/lldbtest.py
    lldb/source/API/SBModule.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/bindings/interface/SBModule.i b/lldb/bindings/interface/SBModule.i
index e902af0c49ce..d64391a40d7c 100644
--- a/lldb/bindings/interface/SBModule.i
+++ b/lldb/bindings/interface/SBModule.i
@@ -353,6 +353,17 @@ public:
     static uint32_t
     GetNumberAllocatedModules();
 
+    %feature("docstring", "
+    Removes all modules which are no longer needed by any part of LLDB from
+    the module cache.
+
+    This is an implementation detail exposed for testing and should not be
+    relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce
+    LLDB's memory consumption during execution.
+    ") GarbageCollectAllocatedModules;
+    static void
+    GarbageCollectAllocatedModules();
+
     STRING_EXTENSION(SBModule)
 
 #ifdef SWIGPYTHON

diff  --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h
index 859eaffe89a0..ec6e7c21b058 100644
--- a/lldb/include/lldb/API/SBModule.h
+++ b/lldb/include/lldb/API/SBModule.h
@@ -291,6 +291,9 @@ class LLDB_API SBModule {
   /// Get the number of global modules.
   static uint32_t GetNumberAllocatedModules();
 
+  /// Remove any global modules which are no longer needed.
+  static void GarbageCollectAllocatedModules();
+
 private:
   friend class SBAddress;
   friend class SBFrame;

diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index ba1556794366..724826de63fa 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1094,6 +1094,17 @@ def tearDown(self):
         lldb.SBDebugger.Destroy(self.dbg)
         del self.dbg
 
+        # All modules should be orphaned now so that they can be cleared from
+        # the shared module cache.
+        lldb.SBModule.GarbageCollectAllocatedModules()
+
+        # Modules are not orphaned during reproducer replay because they're
+        # leaked on purpose.
+        if not configuration.is_reproducer():
+            # Assert that the global module cache is empty.
+            self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0)
+
+
     # =========================================================
     # Various callbacks to allow introspection of test progress
     # =========================================================
@@ -2068,13 +2079,9 @@ def tearDown(self):
         for target in targets:
             self.dbg.DeleteTarget(target)
 
-        # Modules are not orphaned during reproducer replay because they're
-        # leaked on purpose.
         if not configuration.is_reproducer():
             # Assert that all targets are deleted.
-            assert self.dbg.GetNumTargets() == 0
-            # Assert that the global module cache is empty.
-            assert lldb.SBModule.GetNumberAllocatedModules() == 0
+            self.assertEqual(self.dbg.GetNumTargets(), 0)
 
         # Do this last, to make sure it's in reverse order from how we setup.
         Base.tearDown(self)

diff  --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index c30529b37eb1..883319b8078c 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -690,6 +690,13 @@ uint32_t SBModule::GetNumberAllocatedModules() {
   return Module::GetNumberAllocatedModules();
 }
 
+void SBModule::GarbageCollectAllocatedModules() {
+  LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBModule,
+                                    GarbageCollectAllocatedModules);
+  const bool mandatory = false;
+  ModuleList::RemoveOrphanSharedModules(mandatory);
+}
+
 namespace lldb_private {
 namespace repro {
 


        


More information about the lldb-commits mailing list