Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lldb/bindings/interface/SBSaveCoreOptionsDocstrings.i
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ Note that currently ELF Core files are not supported."
Get an SBThreadCollection of all threads marked to be saved. This collection is not sorted according to insertion order."
) lldb::SBSaveCoreOptions::GetThreadsToSave;

%feature("docstring", "
Get the current total number of bytes the core is expected to have, excluding the overhead of the core file format.
Requires both a Process and a Style to be specified. An error will be returned if the provided options would result in no data being saved."
) lldb::SBSaveCoreOptions::GetCurrentSizeInBytes;

%feature("docstring", "
Unset all options."
) lldb::SBSaveCoreOptions::Clear;
13 changes: 13 additions & 0 deletions lldb/include/lldb/API/SBSaveCoreOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 have
/// excluding 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();

Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/SaveCoreOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class SaveCoreOptions {

lldb_private::ThreadCollection::collection GetThreadsToSave() const;

llvm::Expected<uint64_t> GetCurrentSizeInBytes();

void Clear();

private:
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/API/SBSaveCoreOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ void SBSaveCoreOptions::Clear() {
m_opaque_up->Clear();
}

uint64_t SBSaveCoreOptions::GetCurrentSizeInBytes(SBError &error) {
LLDB_INSTRUMENT_VA(this, error);
llvm::Expected<uint64_t> expected_bytes =
m_opaque_up->GetCurrentSizeInBytes();
if (!expected_bytes) {
error =
SBError(lldb_private::Status::FromError(expected_bytes.takeError()));
return 0;
}
// Clear the error, so if the clearer uses it we set it to success.
error.Clear();
return *expected_bytes;
}

lldb_private::SaveCoreOptions &SBSaveCoreOptions::ref() const {
return *m_opaque_up.get();
}
21 changes: 21 additions & 0 deletions lldb/source/Symbol/SaveCoreOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ SaveCoreOptions::GetThreadsToSave() const {
return thread_collection;
}

llvm::Expected<uint64_t> SaveCoreOptions::GetCurrentSizeInBytes() {
Status error;
if (!m_process_sp)
return Status::FromErrorString("Requires a process to be set.").takeError();

error = EnsureValidConfiguration(m_process_sp);
if (error.Fail())
return error.takeError();

CoreFileMemoryRanges ranges;
error = m_process_sp->CalculateCoreFileSaveRanges(*this, ranges);
if (error.Fail())
return error.takeError();

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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,63 @@ 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_current_size_in_bytes(self):
"""
Tests that ensures GetCurrentSizeInBytes 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()

# Add the memory range of 0x1000-0x1100
process.GetMemoryRegionInfo(0x1000, memory_range)
options.AddMemoryRegionToSave(memory_range)

# Check that we fail when we have no process set
# even though we added a memory region.
error = lldb.SBError()
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Fail(), error.GetCString())

# Check that we don't get an error now that we've added a process
options.SetProcess(process)
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Success(), error.GetCString())

# Validate the size returned is the same size as the single region we added.
expected_size = memory_range.GetRegionEnd() - memory_range.GetRegionBase()
self.assertEqual(total, expected_size)

def test_get_total_in_bytes_missing_requirements(self):
"""
Tests the matrix of error responses that GetCurrentSizeInBytes
"""

options = lldb.SBSaveCoreOptions()

# No process, no style returns an error.
error = lldb.SBError()
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Fail(), error.GetCString())

# No process returns an error
options.SetStyle(lldb.eSaveCoreCustomOnly)
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Fail(), error.GetCString())

options.Clear()

# No style returns an error
process = self.get_basic_process()
options.SetProcess(process)
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Fail(), error.GetCString())

# Options that result in no valid data returns an error.
options.SetStyle(lldb.eSaveCoreCustomOnly)
total = options.GetCurrentSizeInBytes(error)
self.assertTrue(error.Fail(), error.GetCString())
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ Streams:
Stack:
Start of Memory Range: 0x00007FFFC8DFF000
Content: 'BAADBEEF'
- Type: Memory64List
Memory Ranges:
- Start of Memory Range: 0x1000
Data Size: 0x100
Content : ''
- Start of Memory Range: 0x2000
Data Size: 0x200
Content : ''
Loading