[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)
Greg Clayton via lldb-commits
lldb-commits at lists.llvm.org
Mon Jun 17 22:41:00 PDT 2024
================
@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
size_t size = memory_buffer->getBufferSize();
if (size == 0)
continue;
- AddDirectory(stream, size);
+ error = AddDirectory(stream, size);
+ if (error.Fail())
+ return error;
m_data.AppendData(memory_buffer->getBufferStart(), size);
}
}
+
+ return error;
}
-Status MinidumpFileBuilder::Dump(lldb::FileUP &core_file) const {
- constexpr size_t header_size = sizeof(llvm::minidump::Header);
- constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+ Status error;
+
+ // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+ // bytes of the core file. Thread structures in minidump files can only use
+ // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+ // in accessible with a 32 bit offset.
+ Process::CoreFileMemoryRanges ranges_32;
+ Process::CoreFileMemoryRanges ranges_64;
+ error = m_process_sp->CalculateCoreFileSaveRanges(
+ SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+ if (error.Fail())
+ return error;
+ uint64_t total_size =
+ ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+ std::unordered_set<addr_t> stack_start_addresses;
+ for (const auto &core_range : ranges_32) {
+ stack_start_addresses.insert(core_range.range.start());
+ total_size += core_range.range.size();
+ }
+
+ if (total_size >= UINT32_MAX) {
+ error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+ "exceeds 32b limit. (Num Stacks %zu)",
+ ranges_32.size());
+ return error;
+ }
+
+ Process::CoreFileMemoryRanges all_core_memory_ranges;
+ if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+ error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+ all_core_memory_ranges);
+ if (error.Fail())
+ return error;
+ }
+
+ // After saving the stacks, we start packing as much as we can into 32b.
+ // We apply a generous padding here so that the Directory, MemoryList and
+ // Memory64List sections all begin in 32b addressable space.
+ // Then anything overflow extends into 64b addressable space.
+ total_size +=
+ 256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+ sizeof(llvm::minidump::MemoryDescriptor_64);
----------------
clayborg wrote:
this `total_size` will be wrong if `all_core_memory_ranges` is empty right? If we are saving stacks only, this will be:
```
256 + (0 - stack_start_addresses.size()) * sizeof(llvm::minidump::MemoryDescriptor_64);
```
And we will unsigned underflow but it won't matter because we won't use `total_size`. Best to put a:
```
if (!all_core_memory_ranges.empty()) {
```
around the `total_size` and for loop that iterates over all core ranges to avoid potential issues in the future.
https://github.com/llvm/llvm-project/pull/95312
More information about the lldb-commits
mailing list