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 <jalalo...@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 <jalalo...@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 <jalalo...@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 <jalalo...@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 <jalalo...@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 <jalalo...@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 <jalalo...@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 +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits