[Lldb-commits] [lldb] [LLDB][SBSaveCore] Add Extension to Save a thread and N pointers deep (PR #111601)

Jacob Lalonde via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 10 13:04:32 PDT 2024


https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/111601

>From 2d693e8208ea99fc57b1137668ee0e12777ab767 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Tue, 8 Oct 2024 15:52:45 -0700
Subject: [PATCH 1/5] Create new extension for save core to save a thread and N
 pointers deep

---
 .../interface/SBSaveCoreOptionsExtensions.i   | 31 +++++++++++++++++++
 lldb/bindings/interfaces.swig                 |  1 +
 .../TestProcessSaveCoreMinidump.py            | 22 +++++++++++++
 3 files changed, 54 insertions(+)
 create mode 100644 lldb/bindings/interface/SBSaveCoreOptionsExtensions.i

diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
new file mode 100644
index 00000000000000..668efbf0f932f1
--- /dev/null
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -0,0 +1,31 @@
+#extend lldb::SBSaveCoreOptions {
+#ifdef SWIGPYTHON
+    %pythoncode% {
+        '''Add a thread to the SaveCoreOptions thread list, and follow it's children N pointers deep, adding each memory region to the SaveCoreOptions Memory region list.'''
+        def save_thread_with_heaps(self, thread, num_heaps_deep = 3):
+            self.AddThread(thread)
+            frame = thread.GetFrameAtIndex(0)
+            process = thread.GetProcess()
+            queue = []
+            for var in frame.locals:
+                if var.TypeIsPointerType():
+                    queue.append(var.Dereference())
+            
+            while (num_heaps_deep > 0 and len(queue) > 0):
+                queue_size = len(queue)
+                for i in range(0, queue_size):
+                    var = queue.pop(0)
+                    memory_region = lldb.SBMemoryRegionInfo()
+                    process.GetMemoryRegionInfo(var.GetAddress().GetOffset(), memory_region)
+                    self.AddMemoryRegionToSave(memory_region)
+                    /* 
+                    We only check for direct pointer children T*, should probably scan 
+                    internal to the children themselves. 
+                    */
+                    for x in var.children:
+                        if x.TypeIsPointerType():
+                            queue.append(x.Dereference())
+
+                num_heaps_deep -= 1
+}
+#endif SWIGPYTHON
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 8a6fed95f0b729..8a82ba28d3f2ae 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -26,6 +26,7 @@
 %include "./interface/SBCommunicationDocstrings.i"
 %include "./interface/SBCompileUnitDocstrings.i"
 %include "./interface/SBSaveCoreOptionsDocstrings.i"
+#include "./interface/SBSaveCoreOptionsExtensions.i"
 %include "./interface/SBDataDocstrings.i"
 %include "./interface/SBDebuggerDocstrings.i"
 %include "./interface/SBDeclarationDocstrings.i"
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
index 03cc415924e0bb..cb5d625f4bffa4 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
@@ -3,6 +3,7 @@
 """
 
 import os
+
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
@@ -470,6 +471,27 @@ def save_core_with_region(self, process, region_index):
             if os.path.isfile(custom_file):
                 os.unlink(custom_file)
 
+    def save_core_one_thread_one_heap(self, process, region_index):
+        try:
+            custom_file = self.getBuildArtifact("core.one_thread_one_heap.dmp")
+            options = lldb.SBSaveCoreOptions()
+            options.SetOutputFile(lldb.SBFileSpec(custom_file))
+            options.SetPluginName("minidump")
+            options.SetStyle(lldb.eSaveCoreCustomOnly)
+            thread = process.GetThreadAtIndex(0)
+            options.save_thread_with_heaps(thread)
+
+            error = process.SaveCore(options)
+            self.assertTrue(error.Success())
+            core_target = self.dbg.CreateTarget(None)
+            core_proc = core_target.LoadCore(custom_file)
+            # proc/pid maps prevent us from checking the number of regions, but
+            # this is mostly a smoke test for the extension.
+            self.assertEqual(core_proc.GetNumThreads(), 1)
+        finally:
+            if os.path.isfile(custom_file):
+                os.unlink(custom_file)
+
     @skipUnlessArch("x86_64")
     @skipUnlessPlatform(["linux"])
     def test_save_minidump_custom_save_style_duplicated_regions(self):

>From dcfa2b25ad8f6961f4da431b863a4f5caefe3ec8 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Tue, 8 Oct 2024 15:53:19 -0700
Subject: [PATCH 2/5] Reword the variable

---
 lldb/bindings/interface/SBSaveCoreOptionsExtensions.i | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index 668efbf0f932f1..5d20aacacadad4 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -2,7 +2,7 @@
 #ifdef SWIGPYTHON
     %pythoncode% {
         '''Add a thread to the SaveCoreOptions thread list, and follow it's children N pointers deep, adding each memory region to the SaveCoreOptions Memory region list.'''
-        def save_thread_with_heaps(self, thread, num_heaps_deep = 3):
+        def save_thread_with_heaps(self, thread, num_pointers_deep = 3):
             self.AddThread(thread)
             frame = thread.GetFrameAtIndex(0)
             process = thread.GetProcess()
@@ -11,7 +11,7 @@
                 if var.TypeIsPointerType():
                     queue.append(var.Dereference())
             
-            while (num_heaps_deep > 0 and len(queue) > 0):
+            while (num_pointers_deep > 0 and len(queue) > 0):
                 queue_size = len(queue)
                 for i in range(0, queue_size):
                     var = queue.pop(0)
@@ -26,6 +26,6 @@
                         if x.TypeIsPointerType():
                             queue.append(x.Dereference())
 
-                num_heaps_deep -= 1
+                num_pointers_deep -= 1
 }
 #endif SWIGPYTHON

>From 3c6114a031b4b6a043a4506562d95753090daa70 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Tue, 8 Oct 2024 17:07:20 -0700
Subject: [PATCH 3/5] Work on fixing test

---
 .../bindings/interface/SBSaveCoreOptionsExtensions.i |  4 ++--
 .../TestProcessSaveCoreMinidump.py                   | 12 +++++++++++-
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index 5d20aacacadad4..1e9d9c62a98a78 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -1,7 +1,6 @@
 #extend lldb::SBSaveCoreOptions {
 #ifdef SWIGPYTHON
     %pythoncode% {
-        '''Add a thread to the SaveCoreOptions thread list, and follow it's children N pointers deep, adding each memory region to the SaveCoreOptions Memory region list.'''
         def save_thread_with_heaps(self, thread, num_pointers_deep = 3):
             self.AddThread(thread)
             frame = thread.GetFrameAtIndex(0)
@@ -27,5 +26,6 @@
                             queue.append(x.Dereference())
 
                 num_pointers_deep -= 1
-}
+    %}
 #endif SWIGPYTHON
+}
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
index cb5d625f4bffa4..7465e4f0bf9aed 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
@@ -471,8 +471,18 @@ def save_core_with_region(self, process, region_index):
             if os.path.isfile(custom_file):
                 os.unlink(custom_file)
 
-    def save_core_one_thread_one_heap(self, process, region_index):
+    @skipUnlessArch("x86_64")
+    @skipUnlessPlatform(["linux"])
+    def test_save_core_one_thread_one_heap(self):
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        custom_file = self.getBuildArtifact("core.custom.dmp")
         try:
+            target = self.dbg.CreateTarget(exe)
+            process = target.LaunchSimple(
+                None, None, self.get_process_working_directory()
+            )
+            self.assertState(process.GetState(), lldb.eStateStopped)
             custom_file = self.getBuildArtifact("core.one_thread_one_heap.dmp")
             options = lldb.SBSaveCoreOptions()
             options.SetOutputFile(lldb.SBFileSpec(custom_file))

>From 7edd4508c86c40c09bad0d8e8b7b5a653315cf04 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Wed, 9 Oct 2024 12:39:34 -0700
Subject: [PATCH 4/5] Relocate  file in interfaces.swig, and use % instead of #
 in

---
 lldb/bindings/interface/SBSaveCoreOptionsExtensions.i | 7 ++++---
 lldb/bindings/interfaces.swig                         | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index 1e9d9c62a98a78..63bf2ef75b42f5 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -1,6 +1,7 @@
-#extend lldb::SBSaveCoreOptions {
+
+%extend lldb::SBSaveCoreOptions {
 #ifdef SWIGPYTHON
-    %pythoncode% {
+    %pythoncode %{
         def save_thread_with_heaps(self, thread, num_pointers_deep = 3):
             self.AddThread(thread)
             frame = thread.GetFrameAtIndex(0)
@@ -27,5 +28,5 @@
 
                 num_pointers_deep -= 1
     %}
-#endif SWIGPYTHON
+#endif
 }
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 8a82ba28d3f2ae..7cb0318df02115 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -26,7 +26,6 @@
 %include "./interface/SBCommunicationDocstrings.i"
 %include "./interface/SBCompileUnitDocstrings.i"
 %include "./interface/SBSaveCoreOptionsDocstrings.i"
-#include "./interface/SBSaveCoreOptionsExtensions.i"
 %include "./interface/SBDataDocstrings.i"
 %include "./interface/SBDebuggerDocstrings.i"
 %include "./interface/SBDeclarationDocstrings.i"
@@ -201,6 +200,7 @@
 %include "./interface/SBProcessExtensions.i"
 %include "./interface/SBProcessInfoListExtensions.i"
 %include "./interface/SBQueueItemExtensions.i"
+#include "./interface/SBSaveCoreOptionsExtensions.i"
 %include "./interface/SBScriptObjectExtensions.i"
 %include "./interface/SBSectionExtensions.i"
 %include "./interface/SBStreamExtensions.i"

>From 5961e8ef7df394147ec16dc5f3db963e6fb7e0b8 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 10 Oct 2024 13:04:04 -0700
Subject: [PATCH 5/5] Find the # that was preventing the extension from being
 included! Switch over to type byte size

---
 .../interface/SBSaveCoreOptionsExtensions.i   | 16 +++++++--------
 lldb/bindings/interfaces.swig                 |  2 +-
 .../TestProcessSaveCoreMinidump.py            | 20 ++++++++++++++++++-
 .../process_save_core_minidump/main.cpp       |  2 +-
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index 63bf2ef75b42f5..d11a143eb7b121 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -1,27 +1,27 @@
 
 %extend lldb::SBSaveCoreOptions {
 #ifdef SWIGPYTHON
-    %pythoncode %{
+    %pythoncode%{
         def save_thread_with_heaps(self, thread, num_pointers_deep = 3):
             self.AddThread(thread)
             frame = thread.GetFrameAtIndex(0)
             process = thread.GetProcess()
             queue = []
             for var in frame.locals:
-                if var.TypeIsPointerType():
+                type = var.GetType()
+                if type.IsPointerType() or type.IsReferenceType():
                     queue.append(var.Dereference())
             
             while (num_pointers_deep > 0 and len(queue) > 0):
                 queue_size = len(queue)
                 for i in range(0, queue_size):
                     var = queue.pop(0)
-                    memory_region = lldb.SBMemoryRegionInfo()
-                    process.GetMemoryRegionInfo(var.GetAddress().GetOffset(), memory_region)
+                    var_type = var.GetType()
+                    addr = var.GetAddress().GetOffset()
+                    memory_region = lldb.SBMemoryRegionInfo(None, addr, addr + var_type.GetByteSize(), False)
                     self.AddMemoryRegionToSave(memory_region)
-                    /* 
-                    We only check for direct pointer children T*, should probably scan 
-                    internal to the children themselves. 
-                    */
+                    # We only check for direct pointer children T*, should probably scan 
+                    # internal to the children themselves. 
                     for x in var.children:
                         if x.TypeIsPointerType():
                             queue.append(x.Dereference())
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 7cb0318df02115..d8fbe522b610d2 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -200,7 +200,7 @@
 %include "./interface/SBProcessExtensions.i"
 %include "./interface/SBProcessInfoListExtensions.i"
 %include "./interface/SBQueueItemExtensions.i"
-#include "./interface/SBSaveCoreOptionsExtensions.i"
+%include "./interface/SBSaveCoreOptionsExtensions.i"
 %include "./interface/SBScriptObjectExtensions.i"
 %include "./interface/SBSectionExtensions.i"
 %include "./interface/SBStreamExtensions.i"
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
index 7465e4f0bf9aed..5ecd0bc61df0e4 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
@@ -489,7 +489,7 @@ def test_save_core_one_thread_one_heap(self):
             options.SetPluginName("minidump")
             options.SetStyle(lldb.eSaveCoreCustomOnly)
             thread = process.GetThreadAtIndex(0)
-            options.save_thread_with_heaps(thread)
+            options.save_thread_with_heaps(thread, 1)
 
             error = process.SaveCore(options)
             self.assertTrue(error.Success())
@@ -498,6 +498,24 @@ def test_save_core_one_thread_one_heap(self):
             # proc/pid maps prevent us from checking the number of regions, but
             # this is mostly a smoke test for the extension.
             self.assertEqual(core_proc.GetNumThreads(), 1)
+            addr = (
+                process.GetThreadAtIndex(0)
+                .GetFrameAtIndex(0)
+                .FindVariable("str")
+                .Dereference()
+                .GetAddress()
+                .GetOffset()
+            )
+            core_addr = (
+                core_proc.GetThreadAtIndex(0)
+                .GetFrameAtIndex(0)
+                .FindVariable("str")
+                .Dereference()
+                .GetAddress()
+                .GetOffset()
+            )
+            self.assertEqual(addr, core_addr)
+
         finally:
             if os.path.isfile(custom_file):
                 os.unlink(custom_file)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/main.cpp b/lldb/test/API/functionalities/process_save_core_minidump/main.cpp
index fa34a371f20647..2c9b64349cc8bc 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/main.cpp
+++ b/lldb/test/API/functionalities/process_save_core_minidump/main.cpp
@@ -18,7 +18,7 @@ size_t h() {
 
 int main() {
   std::thread t1(f);
-
+  char *str = new char[10];
   size_t x = h();
 
   t1.join();



More information about the lldb-commits mailing list