[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
Mon Oct 14 13:28:30 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/7] 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/7] 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/7] 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/7] 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/7] 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();
>From 17c7b2d23383e93b5bdc7757a89fdbcff68b7c6a Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 10 Oct 2024 13:43:47 -0700
Subject: [PATCH 6/7] Add doc string
---
lldb/bindings/interface/SBSaveCoreOptionsExtensions.i | 1 +
1 file changed, 1 insertion(+)
diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index d11a143eb7b121..958cf82e65e47a 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -2,6 +2,7 @@
%extend lldb::SBSaveCoreOptions {
#ifdef SWIGPYTHON
%pythoncode%{
+ '''Add a thread to the SaveCoreOptions thread list, and follow its 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)
>From 267e4c6e7599bf112fb25d13e798ff7fc1f018f3 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 14 Oct 2024 13:28:13 -0700
Subject: [PATCH 7/7] Change test location, and go back to region based instead
of object based
---
.../interface/SBSaveCoreOptionsExtensions.i | 10 +++-
.../process_save_core_minidump/Makefile | 1 -
.../TestProcessSaveCoreMinidump.py | 49 -------------------
.../process_save_core_minidump/main.cpp | 2 +-
.../API/python_api/sbsavecoreoptions/Makefile | 3 ++
.../TestSBSaveCoreOptions.py | 48 ++++++++++++++++--
.../API/python_api/sbsavecoreoptions/main.cpp | 20 ++++++++
7 files changed, 77 insertions(+), 56 deletions(-)
create mode 100644 lldb/test/API/python_api/sbsavecoreoptions/Makefile
create mode 100644 lldb/test/API/python_api/sbsavecoreoptions/main.cpp
diff --git a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
index 958cf82e65e47a..fb0dd5621c06db 100644
--- a/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
+++ b/lldb/bindings/interface/SBSaveCoreOptionsExtensions.i
@@ -4,6 +4,7 @@
%pythoncode%{
'''Add a thread to the SaveCoreOptions thread list, and follow its 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):
+ import lldb
self.AddThread(thread)
frame = thread.GetFrameAtIndex(0)
process = thread.GetProcess()
@@ -19,9 +20,14 @@
var = queue.pop(0)
var_type = var.GetType()
addr = var.GetAddress().GetOffset()
- memory_region = lldb.SBMemoryRegionInfo(None, addr, addr + var_type.GetByteSize(), False)
+ if addr == 0 or addr == None:
+ continue
+ memory_region = lldb.SBMemoryRegionInfo()
+ err = process.GetMemoryRegionInfo(addr, memory_region)
+ if err.Fail():
+ continue
self.AddMemoryRegionToSave(memory_region)
- # We only check for direct pointer children T*, should probably scan
+ # We only check for direct pointer children T*, should probably xscan
# internal to the children themselves.
for x in var.children:
if x.TypeIsPointerType():
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/Makefile b/lldb/test/API/functionalities/process_save_core_minidump/Makefile
index 2d177981fdde16..84694117e0e3fa 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/Makefile
+++ b/lldb/test/API/functionalities/process_save_core_minidump/Makefile
@@ -3,4 +3,3 @@ CXX_SOURCES := main.cpp
CFLAGS_EXTRAS := -lpthread
include Makefile.rules
-
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 5ecd0bc61df0e4..0ef845987ffe82 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py
@@ -471,55 +471,6 @@ def save_core_with_region(self, process, region_index):
if os.path.isfile(custom_file):
os.unlink(custom_file)
- @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))
- options.SetPluginName("minidump")
- options.SetStyle(lldb.eSaveCoreCustomOnly)
- thread = process.GetThreadAtIndex(0)
- options.save_thread_with_heaps(thread, 1)
-
- 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)
- 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)
-
@skipUnlessArch("x86_64")
@skipUnlessPlatform(["linux"])
def test_save_minidump_custom_save_style_duplicated_regions(self):
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 2c9b64349cc8bc..fa34a371f20647 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();
diff --git a/lldb/test/API/python_api/sbsavecoreoptions/Makefile b/lldb/test/API/python_api/sbsavecoreoptions/Makefile
new file mode 100644
index 00000000000000..99998b20bcb050
--- /dev/null
+++ b/lldb/test/API/python_api/sbsavecoreoptions/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py b/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
index 40d0cc7e96ff48..ed412f6cd9d0e5 100644
--- a/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
+++ b/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
@@ -4,15 +4,18 @@
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
+
class SBSaveCoreOptionsAPICase(TestBase):
basic_minidump = "basic_minidump.yaml"
basic_minidump_different_pid = "basic_minidump_different_pid.yaml"
def get_process_from_yaml(self, yaml_file):
minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
- print ("minidump_path: " + minidump_path)
+ print("minidump_path: " + minidump_path)
self.yaml2obj(yaml_file, minidump_path)
- self.assertTrue(os.path.exists(minidump_path), "yaml2obj did not emit a minidump file")
+ self.assertTrue(
+ os.path.exists(minidump_path), "yaml2obj did not emit a minidump file"
+ )
target = self.dbg.CreateTarget(None)
process = target.LoadCore(minidump_path)
self.assertTrue(process.IsValid(), "Process is not valid")
@@ -59,7 +62,6 @@ def test_adding_and_removing_thread(self):
removed_success = options.RemoveThread(thread)
self.assertFalse(removed_success)
-
def test_adding_thread_different_process(self):
"""Test adding and removing a thread from save core options."""
options = lldb.SBSaveCoreOptions()
@@ -79,3 +81,43 @@ def test_adding_thread_different_process(self):
self.assertTrue(error.Fail())
error = options.AddThread(thread)
self.assertTrue(error.Success())
+
+ def verify_linked_list(self, node, depth, max_depth):
+ if depth > max_depth:
+ return
+
+ x_val = node.GetChildMemberWithName("x").GetValueAsUnsigned(0)
+ self.assertEqual(x_val, depth)
+ next_node = node.GetChildMemberWithName("next").Dereference()
+ self.verify_linked_list(next_node, depth + 1, max_depth)
+
+ @skipIfWindows
+ def test_thread_and_heaps_extension(self):
+ """Test the thread and heap extension for save core options."""
+ options = lldb.SBSaveCoreOptions()
+ self.build()
+ (target, process, t, bp) = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("a.out")
+ )
+ main_thread = None
+ for thread_idx in range(process.GetNumThreads()):
+ thread = process.GetThreadAtIndex(thread_idx)
+ frame = thread.GetFrameAtIndex(0)
+ if "main" in frame.name:
+ main_thread = thread
+ break
+ self.assertTrue(main_thread != None)
+ options.save_thread_with_heaps(main_thread, 3)
+ core_file = self.getBuildArtifact("core.one_thread_and_heap.dmp")
+ spec = lldb.SBFileSpec(core_file)
+ options.SetOutputFile(spec)
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+ error = process.SaveCore(options)
+ self.assertTrue(error.Success())
+ core_proc = target.LoadCore(core_file)
+ self.assertTrue(core_proc.IsValid())
+ self.assertEqual(core_proc.GetNumThreads(), 1)
+ frame = core_proc.GetThreadAtIndex(0).GetFrameAtIndex(0)
+ head = frame.FindVariable("head")
+ self.verify_linked_list(head.Dereference(), 0, 3)
diff --git a/lldb/test/API/python_api/sbsavecoreoptions/main.cpp b/lldb/test/API/python_api/sbsavecoreoptions/main.cpp
new file mode 100644
index 00000000000000..12ccfd9600eacc
--- /dev/null
+++ b/lldb/test/API/python_api/sbsavecoreoptions/main.cpp
@@ -0,0 +1,20 @@
+#include <cstddef>
+
+struct Node {
+ Node *next;
+ int x;
+};
+
+int main() {
+ Node *head = new Node();
+ Node *current = head;
+ head->x = 0;
+ for (size_t i = 0; i < 10; i++) {
+ Node *next = new Node();
+ next->x = current->x + 1;
+ current->next = next;
+ current = next;
+ }
+
+ return 0; // break here
+}
More information about the lldb-commits
mailing list