Skip to content

Commit 17ff879

Browse files
committed
Implement new logic to minidump and move objectmacho to the new API. Run git-clang-format
1 parent 02bcc26 commit 17ff879

File tree

7 files changed

+67
-52
lines changed

7 files changed

+67
-52
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,13 +738,13 @@ class Process : public std::enable_shared_from_this<Process>,
738738
/// Helper function for Process::SaveCore(...) that calculates the address
739739
/// ranges that should be saved. This allows all core file plug-ins to save
740740
/// consistent memory ranges given a \a core_style.
741-
Status CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
741+
Status CalculateCoreFileSaveRanges(const SaveCoreOptions &core_options,
742742
CoreFileMemoryRanges &ranges);
743743

744744
/// Helper function for Process::SaveCore(...) that calculates the thread list
745745
/// based upon options set within a given \a core_options object.
746-
ThreadCollection::ThreadIterable
747-
CalculateCoreFileThreadList(SaveCoreOptions &core_options);
746+
std::vector<lldb::ThreadSP>
747+
CalculateCoreFileThreadList(const SaveCoreOptions &core_options);
748748

749749
protected:
750750
virtual JITLoaderList &GetJITLoaders();

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6558,7 +6558,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
65586558

65596559
if (make_core) {
65606560
Process::CoreFileMemoryRanges core_ranges;
6561-
error = process_sp->CalculateCoreFileSaveRanges(core_style, core_ranges);
6561+
error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
65626562
if (error.Success()) {
65636563
const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
65646564
const ByteOrder byte_order = target_arch.GetByteOrder();
@@ -6608,8 +6608,9 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
66086608
mach_header.ncmds = segment_load_commands.size();
66096609
mach_header.flags = 0;
66106610
mach_header.reserved = 0;
6611-
ThreadList &thread_list = process_sp->GetThreadList();
6612-
const uint32_t num_threads = thread_list.GetSize();
6611+
std::vector<ThreadSP> thread_list =
6612+
process_sp->CalculateCoreFileThreadList(options);
6613+
const uint32_t num_threads = thread_list.size();
66136614

66146615
// Make an array of LC_THREAD data items. Each one contains the
66156616
// contents of the LC_THREAD load command. The data doesn't contain
@@ -6622,7 +6623,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
66226623
LC_THREAD_data.SetByteOrder(byte_order);
66236624
}
66246625
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6625-
ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6626+
ThreadSP thread_sp = thread_list.at(thread_idx);
66266627
if (thread_sp) {
66276628
switch (mach_header.cputype) {
66286629
case llvm::MachO::CPU_TYPE_ARM64:
@@ -6730,7 +6731,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
67306731
StructuredData::ArraySP threads(
67316732
std::make_shared<StructuredData::Array>());
67326733
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6733-
ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6734+
ThreadSP thread_sp = thread_list.at(thread_idx);
67346735
StructuredData::DictionarySP thread(
67356736
std::make_shared<StructuredData::Dictionary>());
67366737
thread->AddIntegerItem("thread_id", thread_sp->GetID());

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,13 @@ Status MinidumpFileBuilder::FixThreadStacks() {
588588

589589
Status MinidumpFileBuilder::AddThreadList() {
590590
constexpr size_t minidump_thread_size = sizeof(llvm::minidump::Thread);
591-
lldb_private::ThreadList thread_list = m_process_sp->GetThreadList();
591+
std::vector<ThreadSP> thread_list =
592+
m_process_sp->CalculateCoreFileThreadList(m_save_core_options);
592593

593594
// size of the entire thread stream consists of:
594595
// number of threads and threads array
595596
size_t thread_stream_size = sizeof(llvm::support::ulittle32_t) +
596-
thread_list.GetSize() * minidump_thread_size;
597+
thread_list.size() * minidump_thread_size;
597598
// save for the ability to set up RVA
598599
size_t size_before = GetCurrentDataEndOffset();
599600
Status error;
@@ -602,17 +603,17 @@ Status MinidumpFileBuilder::AddThreadList() {
602603
return error;
603604

604605
llvm::support::ulittle32_t thread_count =
605-
static_cast<llvm::support::ulittle32_t>(thread_list.GetSize());
606+
static_cast<llvm::support::ulittle32_t>(thread_list.size());
606607
m_data.AppendData(&thread_count, sizeof(llvm::support::ulittle32_t));
607608

608609
// Take the offset after the thread count.
609610
m_thread_list_start = GetCurrentDataEndOffset();
610611
DataBufferHeap helper_data;
611612

612-
const uint32_t num_threads = thread_list.GetSize();
613+
const uint32_t num_threads = thread_list.size();
613614
Log *log = GetLog(LLDBLog::Object);
614615
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
615-
ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
616+
ThreadSP thread_sp = thread_list.at(thread_idx);
616617
RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
617618

618619
if (!reg_ctx_sp) {
@@ -819,7 +820,7 @@ Status MinidumpFileBuilder::AddLinuxFileStreams() {
819820
return error;
820821
}
821822

822-
Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
823+
Status MinidumpFileBuilder::AddMemoryList() {
823824
Status error;
824825

825826
// We first save the thread stacks to ensure they fit in the first UINT32_MAX
@@ -828,18 +829,26 @@ Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
828829
// in accessible with a 32 bit offset.
829830
Process::CoreFileMemoryRanges ranges_32;
830831
Process::CoreFileMemoryRanges ranges_64;
831-
error = m_process_sp->CalculateCoreFileSaveRanges(
832-
SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
832+
Process::CoreFileMemoryRanges all_core_memory_ranges;
833+
error = m_process_sp->CalculateCoreFileSaveRanges(m_save_core_options,
834+
all_core_memory_ranges);
833835
if (error.Fail())
834836
return error;
835837

836-
// Calculate totalsize including the current offset.
838+
// Start by saving all of the stacks and ensuring they fit under the 32b
839+
// limit.
837840
uint64_t total_size = GetCurrentDataEndOffset();
838-
total_size += ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
839-
std::unordered_set<addr_t> stack_start_addresses;
840-
for (const auto &core_range : ranges_32) {
841-
stack_start_addresses.insert(core_range.range.start());
842-
total_size += core_range.range.size();
841+
auto iterator = all_core_memory_ranges.begin();
842+
while (iterator != all_core_memory_ranges.end()) {
843+
if (m_saved_stack_ranges.count(iterator->range.start()) > 0) {
844+
// We don't save stacks twice.
845+
ranges_32.push_back(*iterator);
846+
total_size +=
847+
iterator->range.size() + sizeof(llvm::minidump::MemoryDescriptor);
848+
iterator = all_core_memory_ranges.erase(iterator);
849+
} else {
850+
iterator++;
851+
}
843852
}
844853

845854
if (total_size >= UINT32_MAX) {
@@ -849,31 +858,20 @@ Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
849858
return error;
850859
}
851860

852-
Process::CoreFileMemoryRanges all_core_memory_ranges;
853-
if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
854-
error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
855-
all_core_memory_ranges);
856-
if (error.Fail())
857-
return error;
858-
}
859-
860861
// After saving the stacks, we start packing as much as we can into 32b.
861862
// We apply a generous padding here so that the Directory, MemoryList and
862863
// Memory64List sections all begin in 32b addressable space.
863864
// Then anything overflow extends into 64b addressable space.
864865
// All core memeroy ranges will either container nothing on stacks only
865866
// or all the memory ranges including stacks
866867
if (!all_core_memory_ranges.empty())
867-
total_size +=
868-
256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
869-
sizeof(llvm::minidump::MemoryDescriptor_64);
868+
total_size += 256 + (all_core_memory_ranges.size() *
869+
sizeof(llvm::minidump::MemoryDescriptor_64));
870870

871871
for (const auto &core_range : all_core_memory_ranges) {
872872
const addr_t range_size = core_range.range.size();
873-
if (stack_start_addresses.count(core_range.range.start()) > 0)
874-
// Don't double save stacks.
875-
continue;
876-
873+
// We don't need to check for stacks here because we already removed them
874+
// from all_core_memory_ranges.
877875
if (total_size + range_size < UINT32_MAX) {
878876
ranges_32.push_back(core_range);
879877
total_size += range_size;

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ lldb_private::Status WriteString(const std::string &to_write,
7575
class MinidumpFileBuilder {
7676
public:
7777
MinidumpFileBuilder(lldb::FileUP &&core_file,
78-
const lldb::ProcessSP &process_sp)
79-
: m_process_sp(process_sp), m_core_file(std::move(core_file)){};
78+
const lldb::ProcessSP &process_sp,
79+
const lldb_private::SaveCoreOptions &save_core_options)
80+
: m_process_sp(process_sp), m_core_file(std::move(core_file)),
81+
m_save_core_options(save_core_options){};
8082

8183
MinidumpFileBuilder(const MinidumpFileBuilder &) = delete;
8284
MinidumpFileBuilder &operator=(const MinidumpFileBuilder &) = delete;
@@ -103,7 +105,7 @@ class MinidumpFileBuilder {
103105
// Add Exception streams for any threads that stopped with exceptions.
104106
lldb_private::Status AddExceptions();
105107
// Add MemoryList stream, containing dumps of important memory segments
106-
lldb_private::Status AddMemoryList(lldb::SaveCoreStyle core_style);
108+
lldb_private::Status AddMemoryList();
107109
// Add MiscInfo stream, mainly providing ProcessId
108110
lldb_private::Status AddMiscInfo();
109111
// Add informative files about a Linux process
@@ -163,7 +165,9 @@ class MinidumpFileBuilder {
163165
// to duplicate it in the exception data.
164166
std::unordered_map<lldb::tid_t, llvm::minidump::LocationDescriptor>
165167
m_tid_to_reg_ctx;
168+
std::unordered_set<lldb::addr_t> m_saved_stack_ranges;
166169
lldb::FileUP m_core_file;
170+
lldb_private::SaveCoreOptions m_save_core_options;
167171
};
168172

169173
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H

lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
7474
error = maybe_core_file.takeError();
7575
return false;
7676
}
77-
MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp);
77+
MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp,
78+
options);
7879

7980
Log *log = GetLog(LLDBLog::Object);
8081
error = builder.AddHeaderAndCalculateDirectories();
@@ -121,7 +122,7 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
121122

122123
// Note: add memory HAS to be the last thing we do. It can overflow into 64b
123124
// land and many RVA's only support 32b
124-
error = builder.AddMemoryList(core_style);
125+
error = builder.AddMemoryList();
125126
if (error.Fail()) {
126127
LLDB_LOGF(log, "AddMemoryList failed: %s", error.AsCString());
127128
return false;

lldb/source/Symbol/SaveCoreOptions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ int64_t SaveCoreOptions::GetThreadAtIndex(size_t index) const {
7777
}
7878

7979
bool SaveCoreOptions::ShouldSaveThread(lldb::tid_t tid) const {
80+
// If the user specified no threads to save, then we save all threads.
81+
if (m_threads_to_save.empty())
82+
return true;
8083
return m_threads_to_save.count(tid) > 0;
8184
}
8285

lldb/source/Target/Process.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6532,8 +6532,9 @@ static void AddRegion(const MemoryRegionInfo &region, bool try_dirty_pages,
65326532
}
65336533

65346534
static void SaveOffRegionsWithStackPointers(
6535-
Process &process, const MemoryRegionInfos &regions,
6536-
Process::CoreFileMemoryRanges &ranges, std::set<addr_t> &stack_ends) {
6535+
Process &process, const SaveCoreOptions &core_options,
6536+
const MemoryRegionInfos &regions, Process::CoreFileMemoryRanges &ranges,
6537+
std::set<addr_t> &stack_ends) {
65376538
const bool try_dirty_pages = true;
65386539

65396540
// Before we take any dump, we want to save off the used portions of the
@@ -6555,10 +6556,16 @@ static void SaveOffRegionsWithStackPointers(
65556556
if (process.GetMemoryRegionInfo(sp, sp_region).Success()) {
65566557
const size_t stack_head = (sp - red_zone);
65576558
const size_t stack_size = sp_region.GetRange().GetRangeEnd() - stack_head;
6559+
// Even if the SaveCoreOption doesn't want us to save the stack
6560+
// we still need to populate the stack_ends set so it doesn't get saved
6561+
// off in other calls
65586562
sp_region.GetRange().SetRangeBase(stack_head);
65596563
sp_region.GetRange().SetByteSize(stack_size);
65606564
stack_ends.insert(sp_region.GetRange().GetRangeEnd());
6561-
AddRegion(sp_region, try_dirty_pages, ranges);
6565+
// This will return true if the threadlist the user specified is empty,
6566+
// or contains the thread id from thread_sp.
6567+
if (core_options.ShouldSaveThread(thread_sp->GetID()))
6568+
AddRegion(sp_region, try_dirty_pages, ranges);
65626569
}
65636570
}
65646571
}
@@ -6627,10 +6634,11 @@ static void GetCoreFileSaveRangesStackOnly(
66276634
}
66286635
}
66296636

6630-
Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
6637+
Status Process::CalculateCoreFileSaveRanges(const SaveCoreOptions &options,
66316638
CoreFileMemoryRanges &ranges) {
66326639
lldb_private::MemoryRegionInfos regions;
66336640
Status err = GetMemoryRegions(regions);
6641+
SaveCoreStyle core_style = options.GetStyle();
66346642
if (err.Fail())
66356643
return err;
66366644
if (regions.empty())
@@ -6640,7 +6648,7 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
66406648
"eSaveCoreUnspecified");
66416649

66426650
std::set<addr_t> stack_ends;
6643-
SaveOffRegionsWithStackPointers(*this, regions, ranges, stack_ends);
6651+
SaveOffRegionsWithStackPointers(*this, options, regions, ranges, stack_ends);
66446652

66456653
switch (core_style) {
66466654
case eSaveCoreUnspecified:
@@ -6668,16 +6676,16 @@ Status Process::CalculateCoreFileSaveRanges(lldb::SaveCoreStyle core_style,
66686676
return Status(); // Success!
66696677
}
66706678

6671-
ThreadCollection::ThreadIterable
6672-
Process::CalculateCoreFileThreadList(SaveCoreOptions &core_options) {
6673-
ThreadCollection thread_list;
6679+
std::vector<ThreadSP>
6680+
Process::CalculateCoreFileThreadList(const SaveCoreOptions &core_options) {
6681+
std::vector<ThreadSP> thread_list;
66746682
for (const auto &thread : m_thread_list.Threads()) {
66756683
if (core_options.ShouldSaveThread(thread->GetID())) {
6676-
thread_list.AddThread(thread);
6684+
thread_list.push_back(thread);
66776685
}
66786686
}
66796687

6680-
return thread_list.Threads();
6688+
return thread_list;
66816689
}
66826690

66836691
void Process::SetAddressableBitMasks(AddressableBits bit_masks) {

0 commit comments

Comments
 (0)