Skip to content

Commit 572943e

Browse files
authored
[LLDB] Reapply #100443 SBSaveCore Thread list (#104497)
Reapply #100443 and #101770. These were originally reverted due to a test failure and an MSAN failure. I changed the test attribute to restrict to x86 (following the other existing tests). I could not reproduce the test or the MSAN failure and no repo steps were provided.
1 parent d156a5a commit 572943e

26 files changed

+458
-84
lines changed

lldb/include/lldb/API/SBProcess.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ class LLDB_API SBProcess {
586586
friend class SBBreakpointCallbackBaton;
587587
friend class SBBreakpointLocation;
588588
friend class SBCommandInterpreter;
589+
friend class SBSaveCoreOptions;
589590
friend class SBDebugger;
590591
friend class SBExecutionContext;
591592
friend class SBFunction;

lldb/include/lldb/API/SBSaveCoreOptions.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#define LLDB_API_SBSAVECOREOPTIONS_H
1111

1212
#include "lldb/API/SBDefines.h"
13+
#include "lldb/API/SBError.h"
14+
#include "lldb/API/SBFileSpec.h"
15+
#include "lldb/API/SBProcess.h"
16+
#include "lldb/API/SBThread.h"
1317

1418
namespace lldb {
1519

@@ -53,6 +57,29 @@ class LLDB_API SBSaveCoreOptions {
5357
/// \return The output file spec.
5458
SBFileSpec GetOutputFile() const;
5559

60+
/// Set the process to save, or unset if supplied with a default constructed
61+
/// process.
62+
///
63+
/// \param process The process to save.
64+
/// \return Success if process was set, otherwise an error
65+
/// \note This will clear all process specific options if a different process
66+
/// is specified than the current set process, either explicitly from this
67+
/// api, or implicitly from any function that requires a process.
68+
SBError SetProcess(lldb::SBProcess process);
69+
70+
/// Add a thread to save in the core file.
71+
///
72+
/// \param thread The thread to save.
73+
/// \note This will set the process if it is not already set, or return
74+
/// and error if the SBThread is not from the set process.
75+
SBError AddThread(lldb::SBThread thread);
76+
77+
/// Remove a thread from the list of threads to save.
78+
///
79+
/// \param thread The thread to remove.
80+
/// \return True if the thread was removed, false if it was not in the list.
81+
bool RemoveThread(lldb::SBThread thread);
82+
5683
/// Reset all options.
5784
void Clear();
5885

lldb/include/lldb/API/SBThread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class LLDB_API SBThread {
233233
friend class SBBreakpoint;
234234
friend class SBBreakpointLocation;
235235
friend class SBBreakpointCallbackBaton;
236+
friend class SBSaveCoreOptions;
236237
friend class SBExecutionContext;
237238
friend class SBFrame;
238239
friend class SBProcess;
@@ -253,6 +254,8 @@ class LLDB_API SBThread {
253254
SBError ResumeNewPlan(lldb_private::ExecutionContext &exe_ctx,
254255
lldb_private::ThreadPlan *new_plan);
255256

257+
lldb::ThreadSP GetSP() const;
258+
256259
lldb::ExecutionContextRefSP m_opaque_sp;
257260

258261
lldb_private::Thread *operator->();

lldb/include/lldb/Core/PluginManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class PluginManager {
194194
GetObjectFileCreateMemoryCallbackForPluginName(llvm::StringRef name);
195195

196196
static Status SaveCore(const lldb::ProcessSP &process_sp,
197-
const lldb_private::SaveCoreOptions &core_options);
197+
lldb_private::SaveCoreOptions &core_options);
198198

199199
// ObjectContainer
200200
static bool RegisterPlugin(

lldb/include/lldb/Symbol/SaveCoreOptions.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <optional>
1717
#include <string>
18+
#include <unordered_set>
1819

1920
namespace lldb_private {
2021

@@ -32,13 +33,25 @@ class SaveCoreOptions {
3233
void SetOutputFile(lldb_private::FileSpec file);
3334
const std::optional<lldb_private::FileSpec> GetOutputFile() const;
3435

36+
Status SetProcess(lldb::ProcessSP process_sp);
37+
38+
Status AddThread(lldb::ThreadSP thread_sp);
39+
bool RemoveThread(lldb::ThreadSP thread_sp);
40+
bool ShouldThreadBeSaved(lldb::tid_t tid) const;
41+
42+
Status EnsureValidConfiguration(lldb::ProcessSP process_sp) const;
43+
3544
void Clear();
3645

3746
private:
47+
void ClearProcessSpecificData();
48+
3849
std::optional<std::string> m_plugin_name;
3950
std::optional<lldb_private::FileSpec> m_file;
4051
std::optional<lldb::SaveCoreStyle> m_style;
52+
lldb::ProcessSP m_process_sp;
53+
std::unordered_set<lldb::tid_t> m_threads_to_save;
4154
};
4255
} // namespace lldb_private
4356

44-
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_SaveCoreOPTIONS_H
57+
#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_SAVECOREOPTIONS_H

lldb/include/lldb/Target/Process.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,9 +738,15 @@ 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

744+
/// Helper function for Process::SaveCore(...) that calculates the thread list
745+
/// based upon options set within a given \a core_options object.
746+
/// \note If there is no thread list defined, all threads will be saved.
747+
std::vector<lldb::ThreadSP>
748+
CalculateCoreFileThreadList(const SaveCoreOptions &core_options);
749+
744750
protected:
745751
virtual JITLoaderList &GetJITLoaders();
746752

lldb/include/lldb/lldb-private-interfaces.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ typedef ObjectFile *(*ObjectFileCreateMemoryInstance)(
5757
const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
5858
const lldb::ProcessSP &process_sp, lldb::addr_t offset);
5959
typedef bool (*ObjectFileSaveCore)(const lldb::ProcessSP &process_sp,
60-
const lldb_private::SaveCoreOptions &options,
60+
lldb_private::SaveCoreOptions &options,
6161
Status &error);
6262
typedef EmulateInstruction *(*EmulateInstructionCreateInstance)(
6363
const ArchSpec &arch, InstructionType inst_type);

lldb/source/API/SBSaveCoreOptions.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "lldb/API/SBSaveCoreOptions.h"
10-
#include "lldb/API/SBError.h"
11-
#include "lldb/API/SBFileSpec.h"
1210
#include "lldb/Host/FileSystem.h"
1311
#include "lldb/Symbol/SaveCoreOptions.h"
1412
#include "lldb/Utility/Instrumentation.h"
@@ -77,6 +75,21 @@ lldb::SaveCoreStyle SBSaveCoreOptions::GetStyle() const {
7775
return m_opaque_up->GetStyle();
7876
}
7977

78+
SBError SBSaveCoreOptions::SetProcess(lldb::SBProcess process) {
79+
LLDB_INSTRUMENT_VA(this, process);
80+
return m_opaque_up->SetProcess(process.GetSP());
81+
}
82+
83+
SBError SBSaveCoreOptions::AddThread(lldb::SBThread thread) {
84+
LLDB_INSTRUMENT_VA(this, thread);
85+
return m_opaque_up->AddThread(thread.GetSP());
86+
}
87+
88+
bool SBSaveCoreOptions::RemoveThread(lldb::SBThread thread) {
89+
LLDB_INSTRUMENT_VA(this, thread);
90+
return m_opaque_up->RemoveThread(thread.GetSP());
91+
}
92+
8093
void SBSaveCoreOptions::Clear() {
8194
LLDB_INSTRUMENT_VA(this);
8295
m_opaque_up->Clear();

lldb/source/API/SBThread.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,8 @@ bool SBThread::SafeToCallFunctions() {
13371337
return true;
13381338
}
13391339

1340+
lldb::ThreadSP SBThread::GetSP() const { return m_opaque_sp->GetThreadSP(); }
1341+
13401342
lldb_private::Thread *SBThread::operator->() {
13411343
return get();
13421344
}

lldb/source/Core/PluginManager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
702702
}
703703

704704
Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
705-
const lldb_private::SaveCoreOptions &options) {
705+
lldb_private::SaveCoreOptions &options) {
706706
Status error;
707707
if (!options.GetOutputFile()) {
708708
error.SetErrorString("No output file specified");
@@ -714,6 +714,10 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
714714
return error;
715715
}
716716

717+
error = options.EnsureValidConfiguration(process_sp);
718+
if (error.Fail())
719+
return error;
720+
717721
if (!options.GetPluginName().has_value()) {
718722
// Try saving core directly from the process plugin first.
719723
llvm::Expected<bool> ret =

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

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6347,22 +6347,24 @@ struct segment_vmaddr {
63476347
// are some multiple passes over the image list while calculating
63486348
// everything.
63496349

6350-
static offset_t CreateAllImageInfosPayload(
6351-
const lldb::ProcessSP &process_sp, offset_t initial_file_offset,
6352-
StreamString &all_image_infos_payload, SaveCoreStyle core_style) {
6350+
static offset_t
6351+
CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,
6352+
offset_t initial_file_offset,
6353+
StreamString &all_image_infos_payload,
6354+
lldb_private::SaveCoreOptions &options) {
63536355
Target &target = process_sp->GetTarget();
63546356
ModuleList modules = target.GetImages();
63556357

63566358
// stack-only corefiles have no reason to include binaries that
63576359
// are not executing; we're trying to make the smallest corefile
63586360
// we can, so leave the rest out.
6359-
if (core_style == SaveCoreStyle::eSaveCoreStackOnly)
6361+
if (options.GetStyle() == SaveCoreStyle::eSaveCoreStackOnly)
63606362
modules.Clear();
63616363

63626364
std::set<std::string> executing_uuids;
6363-
ThreadList &thread_list(process_sp->GetThreadList());
6364-
for (uint32_t i = 0; i < thread_list.GetSize(); i++) {
6365-
ThreadSP thread_sp = thread_list.GetThreadAtIndex(i);
6365+
std::vector<ThreadSP> thread_list =
6366+
process_sp->CalculateCoreFileThreadList(options);
6367+
for (const ThreadSP &thread_sp : thread_list) {
63666368
uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
63676369
for (uint32_t j = 0; j < stack_frame_count; j++) {
63686370
StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
@@ -6520,16 +6522,17 @@ struct page_object {
65206522
};
65216523

65226524
bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
6523-
const lldb_private::SaveCoreOptions &options,
6525+
lldb_private::SaveCoreOptions &options,
65246526
Status &error) {
6525-
auto core_style = options.GetStyle();
6526-
if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
6527-
core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
65286527
// The FileSpec and Process are already checked in PluginManager::SaveCore.
65296528
assert(options.GetOutputFile().has_value());
65306529
assert(process_sp);
65316530
const FileSpec outfile = options.GetOutputFile().value();
65326531

6532+
// MachO defaults to dirty pages
6533+
if (options.GetStyle() == SaveCoreStyle::eSaveCoreUnspecified)
6534+
options.SetStyle(eSaveCoreDirtyOnly);
6535+
65336536
Target &target = process_sp->GetTarget();
65346537
const ArchSpec target_arch = target.GetArchitecture();
65356538
const llvm::Triple &target_triple = target_arch.GetTriple();
@@ -6559,7 +6562,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
65596562

65606563
if (make_core) {
65616564
Process::CoreFileMemoryRanges core_ranges;
6562-
error = process_sp->CalculateCoreFileSaveRanges(core_style, core_ranges);
6565+
error = process_sp->CalculateCoreFileSaveRanges(options, core_ranges);
65636566
if (error.Success()) {
65646567
const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
65656568
const ByteOrder byte_order = target_arch.GetByteOrder();
@@ -6730,8 +6733,8 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
67306733
std::make_shared<StructuredData::Dictionary>());
67316734
StructuredData::ArraySP threads(
67326735
std::make_shared<StructuredData::Array>());
6733-
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
6734-
ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
6736+
for (const ThreadSP &thread_sp :
6737+
process_sp->CalculateCoreFileThreadList(options)) {
67356738
StructuredData::DictionarySP thread(
67366739
std::make_shared<StructuredData::Dictionary>());
67376740
thread->AddIntegerItem("thread_id", thread_sp->GetID());
@@ -6754,7 +6757,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
67546757
all_image_infos_lcnote_up->payload_file_offset = file_offset;
67556758
file_offset = CreateAllImageInfosPayload(
67566759
process_sp, file_offset, all_image_infos_lcnote_up->payload,
6757-
core_style);
6760+
options);
67586761
lc_notes.push_back(std::move(all_image_infos_lcnote_up));
67596762

67606763
// Add LC_NOTE load commands

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
6262
lldb_private::ModuleSpecList &specs);
6363

6464
static bool SaveCore(const lldb::ProcessSP &process_sp,
65-
const lldb_private::SaveCoreOptions &options,
65+
lldb_private::SaveCoreOptions &options,
6666
lldb_private::Status &error);
6767

6868
static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset,

0 commit comments

Comments
 (0)