Skip to content

Commit 194d6e3

Browse files
committed
Make the thread list for SBSaveCoreOptions iterable
1 parent 91892e8 commit 194d6e3

File tree

6 files changed

+114
-11
lines changed

6 files changed

+114
-11
lines changed

lldb/include/lldb/API/SBSaveCoreOptions.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ class LLDB_API SBSaveCoreOptions {
111111
/// style specific regions.
112112
SBError AddMemoryRegionToSave(const SBMemoryRegionInfo &region);
113113

114+
/// Get the number of Threads to be saved
115+
///
116+
/// \returns
117+
/// The count of Threads to be saved.
118+
uint32_t GetNumThreads() const;
119+
120+
/// Get the Thread at the specified index.
121+
///
122+
/// \param [in] idx
123+
/// The index of the thread to return.
124+
/// \returns
125+
/// The thread at the specified index, or an empty thread if the index is
126+
/// greater than or equal to the number of threads.
127+
lldb::SBThread GetThreadAtIndex(uint32_t idx) const;
128+
114129
/// Reset all options.
115130
void Clear();
116131

lldb/include/lldb/Symbol/SaveCoreOptions.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "lldb/Utility/RangeMap.h"
1414

1515
#include <optional>
16-
#include <set>
1716
#include <string>
1817
#include <unordered_set>
1918

@@ -47,6 +46,9 @@ class SaveCoreOptions {
4746

4847
void AddMemoryRegionToSave(const lldb_private::MemoryRegionInfo &region);
4948

49+
std::optional<lldb::ThreadSP> GetThreadAtIndex(uint32_t idx) const;
50+
uint32_t GetNumThreads() const;
51+
5052
void Clear();
5153

5254
private:
@@ -56,8 +58,10 @@ class SaveCoreOptions {
5658
std::optional<lldb_private::FileSpec> m_file;
5759
std::optional<lldb::SaveCoreStyle> m_style;
5860
lldb::ProcessSP m_process_sp;
59-
std::unordered_set<lldb::tid_t> m_threads_to_save;
61+
std::unordered_map<lldb::tid_t, lldb::ThreadSP> m_threads_to_save;
6062
MemoryRanges m_regions_to_save;
63+
64+
std::vector<lldb::tid_t> m_thread_indexes; // Indexes into m_threads_to_save
6165
};
6266
} // namespace lldb_private
6367

lldb/source/API/SBSaveCoreOptions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ SBSaveCoreOptions::AddMemoryRegionToSave(const SBMemoryRegionInfo &region) {
100100
return SBError();
101101
}
102102

103+
uint32_t lldb::SBSaveCoreOptions::GetNumThreads() const {
104+
LLDB_INSTRUMENT_VA(this);
105+
return m_opaque_up->GetNumThreads();
106+
}
107+
108+
SBThread SBSaveCoreOptions::GetThreadAtIndex(uint32_t idx) const {
109+
LLDB_INSTRUMENT_VA(this, idx);
110+
std::optional<lldb::ThreadSP> thread_sp = m_opaque_up->GetThreadAtIndex(idx);
111+
if (thread_sp)
112+
return SBThread(thread_sp.value());
113+
return SBThread();
114+
}
115+
103116
void SBSaveCoreOptions::Clear() {
104117
LLDB_INSTRUMENT_VA(this);
105118
m_opaque_up->Clear();

lldb/source/Symbol/SaveCoreOptions.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,33 @@ Status SaveCoreOptions::AddThread(lldb::ThreadSP thread_sp) {
8787
m_process_sp = thread_sp->GetProcess();
8888
}
8989

90-
m_threads_to_save.insert(thread_sp->GetID());
90+
m_threads_to_save.insert({thread_sp->GetID(), thread_sp});
91+
m_thread_indexes.push_back(thread_sp->GetID());
9192
return error;
9293
}
9394

9495
bool SaveCoreOptions::RemoveThread(lldb::ThreadSP thread_sp) {
95-
return thread_sp && m_threads_to_save.erase(thread_sp->GetID()) > 0;
96+
if (!thread_sp)
97+
return false;
98+
if (m_threads_to_save.erase(thread_sp->GetID()) == 0)
99+
return false;
100+
101+
auto it = std::find(m_thread_indexes.begin(), m_thread_indexes.end(),
102+
thread_sp->GetID());
103+
m_thread_indexes.erase(it);
104+
return true;
105+
}
106+
107+
uint32_t SaveCoreOptions::GetNumThreads() const {
108+
return m_threads_to_save.size();
109+
}
110+
111+
std::optional<lldb::ThreadSP>
112+
SaveCoreOptions::GetThreadAtIndex(uint32_t idx) const {
113+
if (idx >= m_thread_indexes.size())
114+
return std::nullopt;
115+
lldb::tid_t tid = m_thread_indexes[idx];
116+
return m_threads_to_save.find(tid)->second;
96117
}
97118

98119
bool SaveCoreOptions::ShouldThreadBeSaved(lldb::tid_t tid) const {
@@ -115,8 +136,8 @@ const MemoryRanges &SaveCoreOptions::GetCoreFileMemoryRanges() const {
115136
return m_regions_to_save;
116137
}
117138

118-
Status SaveCoreOptions::EnsureValidConfiguration(
119-
lldb::ProcessSP process_sp) const {
139+
Status
140+
SaveCoreOptions::EnsureValidConfiguration(lldb::ProcessSP process_sp) const {
120141
Status error;
121142
std::string error_str;
122143
if (!m_threads_to_save.empty() && GetStyle() == lldb::eSaveCoreFull)
@@ -132,10 +153,10 @@ Status SaveCoreOptions::EnsureValidConfiguration(
132153
return error;
133154
}
134155

135-
void SaveCoreOptions::ClearProcessSpecificData() {
156+
void SaveCoreOptions::ClearProcessSpecificData() {
136157
// Deliberately not following the formatter style here to indicate that
137158
// this method will be expanded in the future.
138-
m_threads_to_save.clear();
159+
m_threads_to_save.clear();
139160
}
140161

141162
void SaveCoreOptions::Clear() {
@@ -145,4 +166,5 @@ void SaveCoreOptions::Clear() {
145166
m_threads_to_save.clear();
146167
m_process_sp.reset();
147168
m_regions_to_save.Clear();
169+
m_thread_indexes.clear();
148170
}

lldb/test/API/python_api/sbsavecoreoptions/TestSBSaveCoreOptions.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
from lldbsuite.test.decorators import *
55
from lldbsuite.test.lldbtest import *
66

7+
78
class SBSaveCoreOptionsAPICase(TestBase):
89
basic_minidump = "basic_minidump.yaml"
910
basic_minidump_different_pid = "basic_minidump_different_pid.yaml"
1011

1112
def get_process_from_yaml(self, yaml_file):
1213
minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
13-
print ("minidump_path: " + minidump_path)
14+
print("minidump_path: " + minidump_path)
1415
self.yaml2obj(yaml_file, minidump_path)
15-
self.assertTrue(os.path.exists(minidump_path), "yaml2obj did not emit a minidump file")
16+
self.assertTrue(
17+
os.path.exists(minidump_path), "yaml2obj did not emit a minidump file"
18+
)
1619
target = self.dbg.CreateTarget(None)
1720
process = target.LoadCore(minidump_path)
1821
self.assertTrue(process.IsValid(), "Process is not valid")
@@ -59,7 +62,6 @@ def test_adding_and_removing_thread(self):
5962
removed_success = options.RemoveThread(thread)
6063
self.assertFalse(removed_success)
6164

62-
6365
def test_adding_thread_different_process(self):
6466
"""Test adding and removing a thread from save core options."""
6567
options = lldb.SBSaveCoreOptions()
@@ -79,3 +81,40 @@ def test_adding_thread_different_process(self):
7981
self.assertTrue(error.Fail())
8082
error = options.AddThread(thread)
8183
self.assertTrue(error.Success())
84+
85+
def test_removing_and_adding_insertion_order(self):
86+
"""Test insertion order is maintained when removing and adding threads."""
87+
options = lldb.SBSaveCoreOptions()
88+
process = self.get_basic_process()
89+
threads = []
90+
for x in range(0, 3):
91+
thread = process.GetThreadAtIndex(x)
92+
threads.append(thread)
93+
error = options.AddThread(thread)
94+
self.assertTrue(error.Success())
95+
96+
# Get the middle thread, remove it, and insert it at the end.
97+
middle_thread = threads[1]
98+
self.assertTrue(options.RemoveThread(middle_thread))
99+
num_threads = options.GetNumThreads()
100+
self.assertEqual(num_threads, 2)
101+
error = options.AddThread(middle_thread)
102+
self.assertTrue(error.Success())
103+
num_threads = options.GetNumThreads()
104+
self.assertEqual(num_threads, 3)
105+
thread_at_last_index = options.GetThreadAtIndex(2)
106+
self.assertEqual(thread_at_last_index.id, middle_thread.id)
107+
thread_at_middle_index = options.GetThreadAtIndex(1)
108+
self.assertEqual(thread_at_middle_index.id, threads[2].id)
109+
110+
# Pop the front thread, remove it, and insert it at the end.
111+
front_thread = threads[0]
112+
self.assertTrue(options.RemoveThread(front_thread))
113+
num_threads = options.GetNumThreads()
114+
self.assertEqual(num_threads, 2)
115+
error = options.AddThread(front_thread)
116+
self.assertTrue(error.Success())
117+
num_threads = options.GetNumThreads()
118+
self.assertEqual(num_threads, 3)
119+
thread_at_last_index = options.GetThreadAtIndex(2)
120+
self.assertEqual(thread_at_last_index.id, front_thread.id)

lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,13 @@ Streams:
2424
Stack:
2525
Start of Memory Range: 0x00007FFFC8D0E000
2626
Content: 'DEADBEEF'
27+
- Thread Id: 0x000074DE
28+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000002020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040109600000000000100000000000000000000000000000068E7D0C8FF7F000068E7D0C8FF7F000097E6D0C8FF7F000010109600000000000000000000000000020000000000000088E4D0C8FF7F0000603FFF85C77F0000F00340000000000080E7D0C8FF7F000000000000000000000000000000000000E0034000000000007F0300000000000000000000000000000000000000000000801F0000FFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF252525252525252525252525252525250000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
29+
Stack:
30+
Start of Memory Range: 0x00007FFFC8D0A000
31+
Content: 'BEEFDEAD'
32+
- Thread Id: 0x000074DF
33+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000002020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040109600000000000100000000000000000000000000000068E7D0C8FF7F000068E7D0C8FF7F000097E6D0C8FF7F000010109600000000000000000000000000020000000000000088E4D0C8FF7F0000603FFF85C77F0000F00340000000000080E7D0C8FF7F000000000000000000000000000000000000E0034000000000007F0300000000000000000000000000000000000000000000801F0000FFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF252525252525252525252525252525250000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
34+
Stack:
35+
Start of Memory Range: 0x00007FFFC8DFF000
36+
Content: 'BAADBEEF'

0 commit comments

Comments
 (0)