-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[LLDB][SBSaveCoreOptions] Add new API to expose the expected core size in bytes #138169
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
Conversation
@llvm/pr-subscribers-lldb Author: Jacob Lalonde (Jlalond) ChangesMy current internal work requires some sensitivity to IO usage. I had a work around to calculate the expected size of a Minidump, but I've added this PR so an automated system could look at the expected size of an LLDB generated Minidump and then choose if it has the space or wants to generate it. There are some prerequisites to calculating the correct size, so I have the API take a reference for an SBError, I originally tried to return an SBError and instead take a uint64_t reference, but this made the API very difficult to use in python. Added a test case as well. Full diff: https://github.com/llvm/llvm-project/pull/138169.diff 6 Files Affected:
diff --git a/lldb/include/lldb/API/SBSaveCoreOptions.h b/lldb/include/lldb/API/SBSaveCoreOptions.h
index c6d2ab6099b3c..4c051353a714e 100644
--- a/lldb/include/lldb/API/SBSaveCoreOptions.h
+++ b/lldb/include/lldb/API/SBSaveCoreOptions.h
@@ -119,6 +119,19 @@ class LLDB_API SBSaveCoreOptions {
/// an empty collection will be returned.
SBThreadCollection GetThreadsToSave() const;
+ /// Get the current total number of bytes the core is expected to be but not
+ /// including the overhead of the core file format. Requires a Process and
+ /// Style to be specified.
+ ///
+ /// \note
+ /// This can cause some modification of the underlying data store
+ /// as regions with no permissions, or invalid permissions will be removed
+ /// and stacks will be minified up to their stack pointer + the redzone.
+ ///
+ /// \returns
+ /// The expected size of the data contained in the core in bytes.
+ uint64_t GetCurrentSizeInBytes(SBError &error);
+
/// Reset all options.
void Clear();
diff --git a/lldb/include/lldb/Symbol/SaveCoreOptions.h b/lldb/include/lldb/Symbol/SaveCoreOptions.h
index bcf0087fbea5c..319d44a6b0c87 100644
--- a/lldb/include/lldb/Symbol/SaveCoreOptions.h
+++ b/lldb/include/lldb/Symbol/SaveCoreOptions.h
@@ -49,6 +49,8 @@ class SaveCoreOptions {
lldb_private::ThreadCollection::collection GetThreadsToSave() const;
+ uint64_t GetCurrentSizeInBytes(Status &error);
+
void Clear();
private:
diff --git a/lldb/source/API/SBSaveCoreOptions.cpp b/lldb/source/API/SBSaveCoreOptions.cpp
index 35b9da569dfa1..b67df513fe91b 100644
--- a/lldb/source/API/SBSaveCoreOptions.cpp
+++ b/lldb/source/API/SBSaveCoreOptions.cpp
@@ -114,6 +114,11 @@ void SBSaveCoreOptions::Clear() {
m_opaque_up->Clear();
}
+uint64_t SBSaveCoreOptions::GetCurrentSizeInBytes(SBError &error) {
+ LLDB_INSTRUMENT_VA(this, error);
+ return m_opaque_up->GetCurrentSizeInBytes(error.ref());
+}
+
lldb_private::SaveCoreOptions &SBSaveCoreOptions::ref() const {
return *m_opaque_up.get();
}
diff --git a/lldb/source/Symbol/SaveCoreOptions.cpp b/lldb/source/Symbol/SaveCoreOptions.cpp
index c9f6efeb25d22..1da3e1cc9f834 100644
--- a/lldb/source/Symbol/SaveCoreOptions.cpp
+++ b/lldb/source/Symbol/SaveCoreOptions.cpp
@@ -145,6 +145,24 @@ SaveCoreOptions::GetThreadsToSave() const {
return thread_collection;
}
+uint64_t SaveCoreOptions::GetCurrentSizeInBytes(Status &error) {
+ if (!m_process_sp) {
+ error = Status::FromErrorString("Requires a process to be set.");
+ return 0;
+ }
+
+ CoreFileMemoryRanges ranges;
+ error = m_process_sp->CalculateCoreFileSaveRanges(*this, ranges);
+ if (error.Fail())
+ return 0;
+
+ uint64_t total_in_bytes = 0;
+ for (auto& core_range : ranges)
+ total_in_bytes += core_range.data.range.size();
+
+ return total_in_bytes;
+}
+
void SaveCoreOptions::ClearProcessSpecificData() {
// Deliberately not following the formatter style here to indicate that
// this method will be expanded in the future.
diff --git a/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py b/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
index ace84e8497a59..215f8440cc68a 100644
--- a/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
+++ b/lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py
@@ -104,3 +104,24 @@ def test_removing_and_adding_insertion_order(self):
thread_collection = options.GetThreadsToSave()
self.assertEqual(thread_collection.GetSize(), 3)
self.assertIn(middle_thread, thread_collection)
+
+ def test_get_total_in_bytes(self):
+ """
+ Tests that get total in bytes properly returns an error without a process,
+ and the readable regions with a process.
+ """
+
+ options = lldb.SBSaveCoreOptions()
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+ process = self.get_basic_process()
+ memory_range = lldb.SBMemoryRegionInfo()
+ process.GetMemoryRegionInfo(0x7FFF12A84030, memory_range)
+ options.AddMemoryRegionToSave(memory_range)
+ error = lldb.SBError()
+ total = options.GetCurrentSizeInBytes(error)
+ self.assertTrue(error.Fail(), error.GetCString())
+ options.SetProcess(process)
+ total = options.GetCurrentSizeInBytes(error)
+ self.assertTrue(error.Success(), error.GetCString())
+ expected_size = memory_range.GetRegionEnd() - memory_range.GetRegionBase()
+ self.assertEqual(total, expected_size)
diff --git a/lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml b/lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml
index 96302fbfb6b5c..5033787019d7b 100644
--- a/lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml
+++ b/lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml
@@ -34,3 +34,8 @@ Streams:
Stack:
Start of Memory Range: 0x00007FFFC8DFF000
Content: 'BAADBEEF'
+ - Type: Memory64List
+ Memory Ranges:
+ - Start of Memory Range: 0x7FFF12A84030
+ Data Size: 0x2FD0
+ Content : ''
|
✅ With the latest revision this PR passed the Python code formatter. |
@bulbazord as always thanks for your insight Alex. I added a docstring with your improved comment, almost forgot about that. |
02231e9
to
0f5c5a2
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
0f5c5a2
to
a823853
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few suggestions for expanding test coverage.
Regarding your comment
I have the API take a reference for an SBError, I originally tried to return an SBError and instead take a uint64_t reference, but this made the API very difficult to use in python.
It looks there is precedent for doing this in other API calls (e.g. SBProcess.WriteMemory) and seems like a fine choice to me
https://lldb.llvm.org/python_api/lldb.SBProcess.html#lldb.SBProcess.WriteMemory
@dmpots Thanks for the feedback, I implemented several more test cases, and fixed those typos. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
My current internal work requires some sensitivity to IO usage. I had a work around to calculate the expected size of a Minidump, but I've added this PR so an automated system could look at the expected size of an LLDB generated Minidump and then choose if it has the space or wants to generate it.
There are some prerequisites to calculating the correct size, so I have the API take a reference for an SBError, I originally tried to return an SBError and instead take a uint64_t reference, but this made the API very difficult to use in python.
Added a test case as well.