Skip to content

Commit 5d7f2a6

Browse files
committed
MSquash merge lldb changes and drop llvm changes
1 parent c014db4 commit 5d7f2a6

File tree

7 files changed

+138
-65
lines changed

7 files changed

+138
-65
lines changed

lldb/source/Plugins/Process/minidump/MinidumpParser.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,16 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
417417
return filtered_modules;
418418
}
419419

420-
const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() {
421-
auto ExpectedStream = GetMinidumpFile().getExceptionStream();
420+
std::optional<std::vector<const minidump::ExceptionStream *>>
421+
MinidumpParser::GetExceptionStreams() {
422+
auto ExpectedStream = GetMinidumpFile().getExceptionStreams();
422423
if (ExpectedStream)
423-
return &*ExpectedStream;
424+
return ExpectedStream.get();
424425

425426
LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(),
426427
"Failed to read minidump exception stream: {0}");
427-
return nullptr;
428+
429+
return std::nullopt;
428430
}
429431

430432
std::optional<minidump::Range>

lldb/source/Plugins/Process/minidump/MinidumpParser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class MinidumpParser {
8484
// have the same name, it keeps the copy with the lowest load address.
8585
std::vector<const minidump::Module *> GetFilteredModuleList();
8686

87-
const llvm::minidump::ExceptionStream *GetExceptionStream();
87+
std::optional<std::vector<const llvm::minidump::ExceptionStream *>>
88+
GetExceptionStreams();
8889

8990
std::optional<Range> FindMemoryRange(lldb::addr_t addr);
9091

lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
157157
const FileSpec &core_file,
158158
DataBufferSP core_data)
159159
: PostMortemProcess(target_sp, listener_sp, core_file),
160-
m_core_data(std::move(core_data)), m_active_exception(nullptr),
161-
m_is_wow64(false) {}
160+
m_core_data(std::move(core_data)), m_is_wow64(false) {}
162161

163162
ProcessMinidump::~ProcessMinidump() {
164163
Clear();
@@ -209,7 +208,28 @@ Status ProcessMinidump::DoLoadCore() {
209208
GetTarget().SetArchitecture(arch, true /*set_platform*/);
210209

211210
m_thread_list = m_minidump_parser->GetThreads();
212-
m_active_exception = m_minidump_parser->GetExceptionStream();
211+
std::optional<std::vector<const minidump::ExceptionStream *>>
212+
exception_streams = m_minidump_parser->GetExceptionStreams();
213+
214+
if (exception_streams) {
215+
for (const auto *exception_stream : *exception_streams) {
216+
if (!exception_stream) {
217+
error.SetErrorString(
218+
"Minidump returned null pointer for exception stream");
219+
return error;
220+
}
221+
if (!m_exceptions_by_tid
222+
.try_emplace(exception_stream->ThreadId, exception_stream)
223+
.second) {
224+
// We only cast to avoid the warning around converting little endian in
225+
// printf.
226+
error.SetErrorStringWithFormat(
227+
"Duplicate exception stream for tid %" PRIu32,
228+
(uint32_t)exception_stream->ThreadId);
229+
return error;
230+
}
231+
}
232+
}
213233

214234
SetUnixSignals(UnixSignals::Create(GetArchitecture()));
215235

@@ -232,60 +252,57 @@ Status ProcessMinidump::DoDestroy() { return Status(); }
232252

233253
void ProcessMinidump::RefreshStateAfterStop() {
234254

235-
if (!m_active_exception)
236-
return;
237-
238-
constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF;
239-
if (m_active_exception->ExceptionRecord.ExceptionCode ==
240-
BreakpadDumpRequested) {
241-
// This "ExceptionCode" value is a sentinel that is sometimes used
242-
// when generating a dump for a process that hasn't crashed.
243-
244-
// TODO: The definition and use of this "dump requested" constant
245-
// in Breakpad are actually Linux-specific, and for similar use
246-
// cases on Mac/Windows it defines different constants, referring
247-
// to them as "simulated" exceptions; consider moving this check
248-
// down to the OS-specific paths and checking each OS for its own
249-
// constant.
250-
return;
251-
}
255+
for (const auto &[_, exception_stream] : m_exceptions_by_tid) {
256+
constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF;
257+
if (exception_stream->ExceptionRecord.ExceptionCode ==
258+
BreakpadDumpRequested) {
259+
// This "ExceptionCode" value is a sentinel that is sometimes used
260+
// when generating a dump for a process that hasn't crashed.
261+
262+
// TODO: The definition and use of this "dump requested" constant
263+
// in Breakpad are actually Linux-specific, and for similar use
264+
// cases on Mac/Windows it defines different constants, referring
265+
// to them as "simulated" exceptions; consider moving this check
266+
// down to the OS-specific paths and checking each OS for its own
267+
// constant.
268+
return;
269+
}
252270

253-
lldb::StopInfoSP stop_info;
254-
lldb::ThreadSP stop_thread;
271+
lldb::StopInfoSP stop_info;
272+
lldb::ThreadSP stop_thread;
255273

256-
Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId);
257-
stop_thread = Process::m_thread_list.GetSelectedThread();
258-
ArchSpec arch = GetArchitecture();
274+
Process::m_thread_list.SetSelectedThreadByID(exception_stream->ThreadId);
275+
stop_thread = Process::m_thread_list.GetSelectedThread();
276+
ArchSpec arch = GetArchitecture();
259277

260-
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
261-
uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode;
278+
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
279+
uint32_t signo = exception_stream->ExceptionRecord.ExceptionCode;
280+
if (signo == 0) {
281+
// No stop.
282+
return;
283+
}
262284

263-
if (signo == 0) {
264-
// No stop.
265-
return;
285+
stop_info = StopInfo::CreateStopReasonWithSignal(*stop_thread, signo);
286+
} else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
287+
stop_info = StopInfoMachException::CreateStopReasonWithMachException(
288+
*stop_thread, exception_stream->ExceptionRecord.ExceptionCode, 2,
289+
exception_stream->ExceptionRecord.ExceptionFlags,
290+
exception_stream->ExceptionRecord.ExceptionAddress, 0);
291+
} else {
292+
std::string desc;
293+
llvm::raw_string_ostream desc_stream(desc);
294+
desc_stream << "Exception "
295+
<< llvm::format_hex(
296+
exception_stream->ExceptionRecord.ExceptionCode, 8)
297+
<< " encountered at address "
298+
<< llvm::format_hex(
299+
exception_stream->ExceptionRecord.ExceptionAddress, 8);
300+
stop_info = StopInfo::CreateStopReasonWithException(
301+
*stop_thread, desc_stream.str().c_str());
266302
}
267303

268-
stop_info = StopInfo::CreateStopReasonWithSignal(
269-
*stop_thread, signo);
270-
} else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
271-
stop_info = StopInfoMachException::CreateStopReasonWithMachException(
272-
*stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2,
273-
m_active_exception->ExceptionRecord.ExceptionFlags,
274-
m_active_exception->ExceptionRecord.ExceptionAddress, 0);
275-
} else {
276-
std::string desc;
277-
llvm::raw_string_ostream desc_stream(desc);
278-
desc_stream << "Exception "
279-
<< llvm::format_hex(
280-
m_active_exception->ExceptionRecord.ExceptionCode, 8)
281-
<< " encountered at address "
282-
<< llvm::format_hex(
283-
m_active_exception->ExceptionRecord.ExceptionAddress, 8);
284-
stop_info = StopInfo::CreateStopReasonWithException(
285-
*stop_thread, desc_stream.str().c_str());
286-
}
287-
288-
stop_thread->SetStopInfo(stop_info);
304+
stop_thread->SetStopInfo(stop_info);
305+
}
289306
}
290307

291308
bool ProcessMinidump::IsAlive() { return true; }
@@ -387,10 +404,8 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list,
387404
LocationDescriptor context_location = thread.Context;
388405

389406
// If the minidump contains an exception context, use it
390-
if (m_active_exception != nullptr &&
391-
m_active_exception->ThreadId == thread.ThreadId) {
392-
context_location = m_active_exception->ThreadContext;
393-
}
407+
if (m_exceptions_by_tid.count(thread.ThreadId) > 0)
408+
context_location = m_exceptions_by_tid[thread.ThreadId]->ThreadContext;
394409

395410
llvm::ArrayRef<uint8_t> context;
396411
if (!m_is_wow64)

lldb/source/Plugins/Process/minidump/ProcessMinidump.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class ProcessMinidump : public PostMortemProcess {
107107
private:
108108
lldb::DataBufferSP m_core_data;
109109
llvm::ArrayRef<minidump::Thread> m_thread_list;
110-
const minidump::ExceptionStream *m_active_exception;
110+
std::unordered_map<uint32_t, const minidump::ExceptionStream *>
111+
m_exceptions_by_tid;
111112
lldb::CommandObjectSP m_command_sp;
112113
bool m_is_wow64;
113114
std::optional<MemoryRegionInfos> m_memory_regions;

lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,17 @@ def test_minidump_memory64list(self):
510510
self.assertTrue(region_info_list.GetMemoryRegionAtIndex(2, region))
511511
self.assertEqual(region.GetRegionBase(), 0x00007fff12a87018)
512512
self.assertTrue(region.GetRegionEnd(), 0x00007fff12a87018 + 0x00000400)
513+
514+
def test_multiple_exceptions_or_signals(self):
515+
"""Test that lldb can read the exception information from the Minidump."""
516+
print("Starting to read multiple-sigsev.yaml")
517+
self.process_from_yaml("multiple-sigsev.yaml")
518+
print("Done reading multiple-sigsev.yaml")
519+
self.check_state()
520+
# This process crashed due to a segmentation fault in both it's threads.
521+
self.assertEqual(self.process.GetNumThreads(), 2)
522+
for i in range(2):
523+
thread = self.process.GetThreadAtIndex(i)
524+
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
525+
stop_description = thread.GetStopDescription(256)
526+
self.assertIn("SIGSEGV", stop_description)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--- !minidump
2+
Streams:
3+
- Type: ThreadList
4+
Threads:
5+
- Thread Id: 0x1B4F23
6+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7+
Stack:
8+
Start of Memory Range: 0x7FFFFFFFD348
9+
Content: ''
10+
- Thread Id: 0x1B6D22
11+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
12+
Stack:
13+
Start of Memory Range: 0x7FFFF75FDE28
14+
Content: ''
15+
- Type: ModuleList
16+
Modules:
17+
- Base of Image: 0x0000000000400000
18+
Size of Image: 0x00017000
19+
Module Name: 'a.out'
20+
CodeView Record: ''
21+
- Type: SystemInfo
22+
Processor Arch: AMD64
23+
Platform ID: Linux
24+
CSD Version: 'Linux 3.13'
25+
CPU:
26+
Vendor ID: GenuineIntel
27+
Version Info: 0x00000000
28+
Feature Info: 0x00000000
29+
- Type: Exception
30+
Thread ID: 0x1B4F23
31+
Exception Record:
32+
Exception Code: 0xB
33+
Thread Context: 00000000
34+
- Type: Exception
35+
Thread ID: 0x1B6D22
36+
Exception Record:
37+
Exception Code: 0xB
38+
Thread Context: 00000000
39+
...

lldb/unittests/Process/minidump/MinidumpParserTest.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,11 @@ TEST_F(MinidumpParserTest, GetFilteredModuleList) {
251251

252252
TEST_F(MinidumpParserTest, GetExceptionStream) {
253253
SetUpData("linux-x86_64.dmp");
254-
const llvm::minidump::ExceptionStream *exception_stream =
255-
parser->GetExceptionStream();
256-
ASSERT_NE(nullptr, exception_stream);
257-
ASSERT_EQ(11UL, exception_stream->ExceptionRecord.ExceptionCode);
254+
std::optional<std::vector<const minidump::ExceptionStream *>>
255+
exception_stream = parser->GetExceptionStreams();
256+
ASSERT_TRUE(exception_stream);
257+
ASSERT_EQ(1UL, exception_stream->size());
258+
ASSERT_EQ(11UL, exception_stream->at(0)->ThreadId);
258259
}
259260

260261
void check_mem_range_exists(MinidumpParser &parser, const uint64_t range_start,

0 commit comments

Comments
 (0)