Skip to content

Commit 178b69a

Browse files
[Core][Multi-threaded] Multi-threaded Core file support for 64 and 32 bit (#99)
1 parent 97a6e02 commit 178b69a

File tree

6 files changed

+203
-45
lines changed

6 files changed

+203
-45
lines changed

lldb/source/Plugins/DynamicLoader/AIX-DYLD/DynamicLoaderAIXDYLD.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,67 @@ void DynamicLoaderAIXDYLD::FillCoreLoaderData(lldb_private::DataExtractor &data,
287287
ptr2 = nullptr;
288288
}
289289
}
290+
free(buffer);
291+
}
292+
293+
void DynamicLoaderAIXDYLD::FillCoreLoader32Data(lldb_private::DataExtractor &data,
294+
uint64_t loader_offset, uint64_t loader_size ) {
295+
296+
Log *log = GetLog(LLDBLog::DynamicLoader);
297+
LLDB_LOGF(log, "DynamicLoaderAIXDYLD::%s()", __FUNCTION__);
298+
static char *buffer = (char *)malloc(loader_size);
299+
if (buffer == NULL) {
300+
LLDB_LOG(log, "Buffer allocation failed error: {0}", std::strerror(errno));
301+
return;
302+
}
303+
char *ptr = buffer, filename[PATH_MAX] = {0}, membername[32] = {0};
304+
uint64_t dataorg, textorg, datasize, textsize, core_offset;
305+
int next = 1;
306+
lldb::offset_t base_offset = loader_offset;
307+
while (next != 0)
308+
{
309+
lldb::offset_t offset = base_offset;
310+
next = data.GetU32(&offset);
311+
core_offset = data.GetU32(&offset);
312+
textorg = data.GetU32(&offset);
313+
textsize = data.GetU32(&offset);
314+
if (textsize == 0 || textorg == 0) {
315+
LLDB_LOGF(log, "Warning: text information might be incomplete");
316+
}
317+
dataorg = data.GetU32(&offset);
318+
datasize = data.GetU32(&offset);
319+
if (datasize == 0 || dataorg == 0) {
320+
LLDB_LOGF(log, "Warning: data information might be incomplete");
321+
}
322+
323+
size_t s1_index = 0, s2_index = 0;
324+
uint8_t byte;
325+
326+
while ((byte = data.GetU8(&offset)) != '\0') {
327+
filename[s1_index++] = static_cast<char>(byte);
328+
}
329+
filename[s1_index] = '\0';
330+
while ((byte = data.GetU8(&offset)) != '\0') {
331+
membername[s2_index++] = static_cast<char>(byte);
332+
}
333+
membername[s2_index] = '\0';
334+
base_offset += next;
335+
char pathWithMember[PATH_MAX] = {0};
336+
if (strlen(membername) > 0) {
337+
sprintf(pathWithMember, "%s(%s)", filename, membername);
338+
} else {
339+
sprintf(pathWithMember, "%s", filename);
340+
}
341+
342+
FileSpec file(pathWithMember);
343+
ModuleSpec module_spec(file, m_process->GetTarget().GetArchitecture());
344+
if (ModuleSP module_sp = m_process->GetTarget().GetOrCreateModule(module_spec, true /* notify */)) {
345+
UpdateLoadedSectionsByType(module_sp, LLDB_INVALID_ADDRESS, (lldb::addr_t)textorg, false, 1);
346+
UpdateLoadedSectionsByType(module_sp, LLDB_INVALID_ADDRESS, (lldb::addr_t)dataorg, false, 2);
347+
// FIXME: .tdata, .bss
348+
}
349+
}
350+
free(buffer);
290351
}
291352

292353
void DynamicLoaderAIXDYLD::FillCoreLoader32Data(lldb_private::DataExtractor &data,

lldb/source/Plugins/Process/aix-core/AIXCore.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ bool AIXCore32Header::ParseUserData(lldb_private::DataExtractor &data,
8484

8585
bool AIXCore32Header::ParseCoreHeader(lldb_private::DataExtractor &data,
8686
lldb::offset_t *offset) {
87+
Log *log = GetLog(LLDBLog::Process);
88+
8789
SignalNum = data.GetU8(offset);
8890
Flag = data.GetU8(offset);
8991
Entries = data.GetU16(offset);
@@ -110,6 +112,19 @@ bool AIXCore32Header::ParseCoreHeader(lldb_private::DataExtractor &data,
110112
int ret = 0;
111113
ret = ParseThreadContext(data, offset);
112114
ret = ParseUserData(data, &offset_to_user);
115+
116+
lldb::offset_t offset_to_threads = ThreadContextOffset;
117+
for (int i = 0; i < NumberOfThreads; i++) {
118+
offset_to_threads = ThreadContextOffset + ((sizeof(mstsave32) +
119+
sizeof(thrdsinfo64)) * i);
120+
LLDB_LOGF(log, "Multi-threaded parsing, offset %x\n", offset_to_threads);
121+
AIXCore32Header temp_header;
122+
ThreadContext32 thread;
123+
temp_header.ParseThreadContext(data, &offset_to_threads);
124+
memcpy(&thread, &temp_header.Fault, sizeof(ThreadContext64));
125+
threads.push_back(std::move(thread));
126+
}
127+
113128
return true;
114129
}
115130

@@ -170,6 +185,8 @@ bool AIXCore64Header::ParseUserData(lldb_private::DataExtractor &data,
170185

171186
bool AIXCore64Header::ParseCoreHeader(lldb_private::DataExtractor &data,
172187
lldb::offset_t *offset) {
188+
Log *log = GetLog(LLDBLog::Process);
189+
173190
SignalNum = data.GetU8(offset);
174191
Flag = data.GetU8(offset);
175192
Entries = data.GetU16(offset);
@@ -201,6 +218,18 @@ bool AIXCore64Header::ParseCoreHeader(lldb_private::DataExtractor &data,
201218
ret = ParseThreadContext(data, offset);
202219
ret = ParseUserData(data, &offset_to_user);
203220

221+
lldb::offset_t offset_to_threads = ThreadContextOffset;
222+
for (int i = 0; i < NumberOfThreads; i++) {
223+
offset_to_threads = ThreadContextOffset + ((sizeof(__context64) +
224+
sizeof(thrdentry64)) * i);
225+
LLDB_LOGF(log, "Multi-threaded parsing, offset %x\n", offset_to_threads);
226+
AIXCore64Header temp_header;
227+
ThreadContext64 thread;
228+
temp_header.ParseThreadContext(data, &offset_to_threads);
229+
memcpy(&thread, &temp_header.Fault, sizeof(ThreadContext64));
230+
threads.push_back(std::move(thread));
231+
}
232+
204233
return ret;
205234

206235
}

lldb/source/Plugins/Process/aix-core/AIXCore.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ struct RegContext {
114114

115115
struct UserData User;
116116

117+
std::vector<ThreadContext64> threads;
118+
117119
AIXCore64Header();
118120

119121
bool ParseCoreHeader(lldb_private::DataExtractor &data,
@@ -175,6 +177,8 @@ struct RegContext {
175177

176178
struct UserData32 User;
177179

180+
std::vector<ThreadContext32> threads;
181+
178182
AIXCore32Header();
179183

180184
bool ParseCoreHeader(lldb_private::DataExtractor &data,

lldb/source/Plugins/Process/aix-core/ProcessAIXCore.cpp

Lines changed: 95 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -198,31 +198,52 @@ lldb_private::DynamicLoader *ProcessAIXCore::GetDynamicLoader() {
198198
void ProcessAIXCore::ParseAIXCoreFile() {
199199

200200
Log *log = GetLog(LLDBLog::Process);
201-
AIXSigInfo siginfo;
202-
ThreadData thread_data;
203201

204202
const lldb_private::UnixSignals &unix_signals = *GetUnixSignals();
205203
const ArchSpec &arch = GetArchitecture();
206204

207-
siginfo.Parse(m_aixcore_header, arch, unix_signals);
208-
thread_data.siginfo = siginfo;
205+
const uint32_t num_threads = m_aixcore_header.NumberOfThreads;
209206
SetID(m_aixcore_header.User.process.pi_pid);
207+
m_thread_data.clear();
208+
m_thread_data.reserve(num_threads > 0 ? (num_threads + 1) : 1);
209+
210+
for (uint32_t i = 0; i <= num_threads; i++) {
210211

211-
thread_data.name.assign (m_aixcore_header.User.process.pi_comm,
212-
strnlen (m_aixcore_header.User.process.pi_comm,
213-
sizeof (m_aixcore_header.User.process.pi_comm)));
214-
215-
lldb::DataBufferSP data_buffer_sp(new lldb_private::DataBufferHeap(sizeof(m_aixcore_header.Fault.context), 0));
216-
217-
memcpy(static_cast<void *>(const_cast<uint8_t *>(data_buffer_sp->GetBytes())),
218-
&m_aixcore_header.Fault.context, sizeof(m_aixcore_header.Fault.context));
219-
220-
lldb_private::DataExtractor data(data_buffer_sp, lldb::eByteOrderBig, 8);
212+
AIXSigInfo siginfo;
213+
ThreadData thread_data;
214+
size_t regs_size;
215+
216+
std::string base_name(m_aixcore_header.User.process.pi_comm,
217+
strnlen (m_aixcore_header.User.process.pi_comm,
218+
sizeof (m_aixcore_header.User.process.pi_comm)));
219+
220+
regs_size = (i == 0) ? sizeof(m_aixcore_header.Fault.context)
221+
: sizeof(m_aixcore_header.threads[i-1].context);
222+
223+
lldb::DataBufferSP regs_buf_sp(new lldb_private::DataBufferHeap(regs_size, 0));
224+
if (i == 0) { // The crash thread
225+
thread_data.tid = m_aixcore_header.Fault.thread.ti_tid;
226+
thread_data.name = base_name;
227+
memcpy(static_cast<void *>(const_cast<uint8_t *>(regs_buf_sp->GetBytes())),
228+
&m_aixcore_header.Fault.context, regs_size);
229+
thread_data.siginfo.Parse(m_aixcore_header, arch, unix_signals);
230+
}
231+
else { // Other threads
232+
thread_data.tid = m_aixcore_header.threads[i-1].thread.ti_tid;
233+
thread_data.name = base_name + "-*thread-" + std::to_string(i) + "*";
234+
235+
memcpy(static_cast<void *>(const_cast<uint8_t *>(regs_buf_sp->GetBytes())),
236+
&m_aixcore_header.threads[i-1].context, regs_size);
237+
}
238+
lldb_private::DataExtractor regs_data(regs_buf_sp, lldb::eByteOrderBig, 8);
239+
thread_data.gpregset = DataExtractor(regs_data, 0, regs_size);
221240

222-
thread_data.gpregset = DataExtractor(data, 0, sizeof(m_aixcore_header.Fault.context));
223-
m_thread_data.push_back(thread_data);
224-
LLDB_LOGF(log, "ProcessAIXCore: Parsing Complete!");
241+
thread_data.prstatus_sig = 0;
242+
243+
m_thread_data.push_back(std::move(thread_data));
225244

245+
LLDB_LOGF(log, "ProcessAIXCore: Parsing Complete! tid %d\n",i);
246+
}
226247
}
227248

228249
void ProcessAIXCore::ParseAIXCore32File() {
@@ -233,25 +254,49 @@ void ProcessAIXCore::ParseAIXCore32File() {
233254

234255
const lldb_private::UnixSignals &unix_signals = *GetUnixSignals();
235256
const ArchSpec &arch = GetArchitecture();
236-
237-
siginfo.Parse(m_aixcore32_header, arch, unix_signals);
238-
thread_data.siginfo = siginfo;
239-
SetID(m_aixcore32_header.User.process.pi_pid);
240-
241-
thread_data.name.assign (m_aixcore32_header.User.process.pi_comm,
242-
strnlen (m_aixcore32_header.User.process.pi_comm,
243-
sizeof (m_aixcore32_header.User.process.pi_comm)));
244-
245-
lldb::DataBufferSP data_buffer_sp(new lldb_private::DataBufferHeap(sizeof(m_aixcore32_header.Fault.context), 0));
246-
247-
memcpy(static_cast<void *>(const_cast<uint8_t *>(data_buffer_sp->GetBytes())),
248-
&m_aixcore32_header.Fault.context, sizeof(m_aixcore32_header.Fault.context));
249-
250-
lldb_private::DataExtractor data(data_buffer_sp, lldb::eByteOrderBig, 8);
251-
252-
thread_data.gpregset = DataExtractor(data, 0, sizeof(m_aixcore32_header.Fault.context));
253-
m_thread_data.push_back(thread_data);
254-
LLDB_LOGF(log, "ProcessAIXCore: Parsing Complete!");
257+
258+
const uint32_t num_threads = m_aixcore32_header.NumberOfThreads;
259+
SetID(m_aixcore32_header.User.process.pi_pid);
260+
m_thread_data.clear();
261+
m_thread_data.reserve(num_threads > 0 ? (num_threads + 1) : 1);
262+
263+
for (uint32_t i = 0; i <= num_threads; i++) {
264+
265+
AIXSigInfo siginfo;
266+
ThreadData thread_data;
267+
size_t regs_size;
268+
269+
std::string base_name(m_aixcore32_header.User.process.pi_comm,
270+
strnlen (m_aixcore32_header.User.process.pi_comm,
271+
sizeof (m_aixcore32_header.User.process.pi_comm)));
272+
273+
regs_size = (i == 0) ? sizeof(m_aixcore32_header.Fault.context)
274+
: sizeof(m_aixcore32_header.threads[i-1].context);
275+
276+
lldb::DataBufferSP regs_buf_sp(new lldb_private::DataBufferHeap(regs_size, 0));
277+
if (i == 0) { // The crash thread
278+
thread_data.tid = m_aixcore32_header.Fault.thread.ti_tid;
279+
thread_data.name = base_name;
280+
memcpy(static_cast<void *>(const_cast<uint8_t *>(regs_buf_sp->GetBytes())),
281+
&m_aixcore32_header.Fault.context, regs_size);
282+
thread_data.siginfo.Parse(m_aixcore32_header, arch, unix_signals);
283+
}
284+
else { // Other threads
285+
thread_data.tid = m_aixcore32_header.threads[i-1].thread.ti_tid;
286+
thread_data.name = base_name + "-*thread-" + std::to_string(i) + "*";
287+
288+
memcpy(static_cast<void *>(const_cast<uint8_t *>(regs_buf_sp->GetBytes())),
289+
&m_aixcore32_header.threads[i-1].context, regs_size);
290+
}
291+
lldb_private::DataExtractor regs_data(regs_buf_sp, lldb::eByteOrderBig, 8);
292+
thread_data.gpregset = DataExtractor(regs_data, 0, regs_size);
293+
294+
thread_data.prstatus_sig = 0;
295+
296+
m_thread_data.push_back(std::move(thread_data));
297+
298+
LLDB_LOGF(log, "ProcessAIXCore: Parsing Complete! tid %d\n",i);
299+
}
255300

256301
}
257302
// Process Control
@@ -337,12 +382,20 @@ Status ProcessAIXCore::DoLoadCore() {
337382
bool ProcessAIXCore::DoUpdateThreadList(ThreadList &old_thread_list,
338383
ThreadList &new_thread_list)
339384
{
340-
const ThreadData &td = m_thread_data[0];
341-
342-
lldb::ThreadSP thread_sp =
343-
std::make_shared<ThreadAIXCore>(*this, td);
344-
new_thread_list.AddThread(thread_sp);
345-
385+
Log *log = GetLog(LLDBLog::Process);
386+
const uint32_t num_threads = m_is64bit ? m_aixcore_header.NumberOfThreads :
387+
m_aixcore32_header.NumberOfThreads;
388+
LLDB_LOGF(log,"Number Of Threads %d\n", num_threads);
389+
for (lldb::tid_t tid = 0; tid <= num_threads; ++tid) {
390+
const ThreadData &td = m_thread_data[tid];
391+
lldb::ThreadSP thread_sp =
392+
std::make_shared<ThreadAIXCore>(*this, td);
393+
if(!thread_sp) {
394+
LLDB_LOGF(log,"Thread not added %d\n", tid);
395+
continue;
396+
}
397+
new_thread_list.AddThread(thread_sp);
398+
}
346399
return true;
347400
}
348401

lldb/source/Plugins/Process/aix-core/ThreadAIXCore.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,18 @@ using namespace lldb_private;
3434

3535
// Construct a Thread object with given data
3636
ThreadAIXCore::ThreadAIXCore(Process &process, const ThreadData &td)
37-
: Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
38-
m_gpregset_data(td.gpregset),
39-
m_siginfo(std::move(td.siginfo)) {}
37+
: Thread(process, td.tid),
38+
m_td(std::move(td)),
39+
m_thread_name(m_td.name),
40+
m_thread_reg_ctx_sp(),
41+
m_gpregset_data(m_td.gpregset),
42+
m_siginfo(std::move(m_td.siginfo)) {
43+
44+
Log *log = GetLog(LLDBLog::Process);
45+
SetName(m_thread_name.c_str());
46+
LLDB_LOGF(log,"ThreadAIXCore created %d, %s\n",
47+
static_cast<uint64_t>(m_td.tid), m_thread_name.c_str());
48+
}
4049

4150
ThreadAIXCore::~ThreadAIXCore() { DestroyThread(); }
4251

@@ -53,6 +62,7 @@ RegisterContextSP ThreadAIXCore::GetRegisterContext() {
5362

5463
RegisterContextSP
5564
ThreadAIXCore::CreateRegisterContextForFrame(StackFrame *frame) {
65+
5666
RegisterContextSP reg_ctx_sp;
5767
uint32_t concrete_frame_idx = 0;
5868

lldb/source/Plugins/Process/aix-core/ThreadAIXCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class ThreadAIXCore : public lldb_private::Thread {
101101

102102
protected:
103103
// Member variables.
104+
ThreadData m_td;
104105
std::string m_thread_name;
105106
lldb::RegisterContextSP m_thread_reg_ctx_sp;
106107

0 commit comments

Comments
 (0)