https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/97470
>From 5d7f2a6fb8dc06b838bf072aca1d8829eb61b316 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde <jalalo...@fb.com> Date: Fri, 6 Sep 2024 13:09:27 -0700 Subject: [PATCH 1/4] MSquash merge lldb changes and drop llvm changes --- .../Process/minidump/MinidumpParser.cpp | 10 +- .../Plugins/Process/minidump/MinidumpParser.h | 3 +- .../Process/minidump/ProcessMinidump.cpp | 125 ++++++++++-------- .../Process/minidump/ProcessMinidump.h | 3 +- .../minidump-new/TestMiniDumpNew.py | 14 ++ .../minidump-new/multiple-sigsev.yaml | 39 ++++++ .../Process/minidump/MinidumpParserTest.cpp | 9 +- 7 files changed, 138 insertions(+), 65 deletions(-) create mode 100644 lldb/test/API/functionalities/postmortem/minidump-new/multiple-sigsev.yaml diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index c099c28a620ecf..b0a6ed6e460daa 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -417,14 +417,16 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() { return filtered_modules; } -const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { - auto ExpectedStream = GetMinidumpFile().getExceptionStream(); +std::optional<std::vector<const minidump::ExceptionStream *>> +MinidumpParser::GetExceptionStreams() { + auto ExpectedStream = GetMinidumpFile().getExceptionStreams(); if (ExpectedStream) - return &*ExpectedStream; + return ExpectedStream.get(); LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(), "Failed to read minidump exception stream: {0}"); - return nullptr; + + return std::nullopt; } std::optional<minidump::Range> diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 222c0ef47fb853..be6364ca6ecdc7 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -84,7 +84,8 @@ class MinidumpParser { // have the same name, it keeps the copy with the lowest load address. std::vector<const minidump::Module *> GetFilteredModuleList(); - const llvm::minidump::ExceptionStream *GetExceptionStream(); + std::optional<std::vector<const llvm::minidump::ExceptionStream *>> + GetExceptionStreams(); std::optional<Range> FindMemoryRange(lldb::addr_t addr); diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index ac1ecbfc0e2e70..f876d666031c9a 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -157,8 +157,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp, const FileSpec &core_file, DataBufferSP core_data) : PostMortemProcess(target_sp, listener_sp, core_file), - m_core_data(std::move(core_data)), m_active_exception(nullptr), - m_is_wow64(false) {} + m_core_data(std::move(core_data)), m_is_wow64(false) {} ProcessMinidump::~ProcessMinidump() { Clear(); @@ -209,7 +208,28 @@ Status ProcessMinidump::DoLoadCore() { GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser->GetThreads(); - m_active_exception = m_minidump_parser->GetExceptionStream(); + std::optional<std::vector<const minidump::ExceptionStream *>> + exception_streams = m_minidump_parser->GetExceptionStreams(); + + if (exception_streams) { + for (const auto *exception_stream : *exception_streams) { + if (!exception_stream) { + error.SetErrorString( + "Minidump returned null pointer for exception stream"); + return error; + } + if (!m_exceptions_by_tid + .try_emplace(exception_stream->ThreadId, exception_stream) + .second) { + // We only cast to avoid the warning around converting little endian in + // printf. + error.SetErrorStringWithFormat( + "Duplicate exception stream for tid %" PRIu32, + (uint32_t)exception_stream->ThreadId); + return error; + } + } + } SetUnixSignals(UnixSignals::Create(GetArchitecture())); @@ -232,60 +252,57 @@ Status ProcessMinidump::DoDestroy() { return Status(); } void ProcessMinidump::RefreshStateAfterStop() { - if (!m_active_exception) - return; - - constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF; - if (m_active_exception->ExceptionRecord.ExceptionCode == - BreakpadDumpRequested) { - // This "ExceptionCode" value is a sentinel that is sometimes used - // when generating a dump for a process that hasn't crashed. - - // TODO: The definition and use of this "dump requested" constant - // in Breakpad are actually Linux-specific, and for similar use - // cases on Mac/Windows it defines different constants, referring - // to them as "simulated" exceptions; consider moving this check - // down to the OS-specific paths and checking each OS for its own - // constant. - return; - } + for (const auto &[_, exception_stream] : m_exceptions_by_tid) { + constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF; + if (exception_stream->ExceptionRecord.ExceptionCode == + BreakpadDumpRequested) { + // This "ExceptionCode" value is a sentinel that is sometimes used + // when generating a dump for a process that hasn't crashed. + + // TODO: The definition and use of this "dump requested" constant + // in Breakpad are actually Linux-specific, and for similar use + // cases on Mac/Windows it defines different constants, referring + // to them as "simulated" exceptions; consider moving this check + // down to the OS-specific paths and checking each OS for its own + // constant. + return; + } - lldb::StopInfoSP stop_info; - lldb::ThreadSP stop_thread; + lldb::StopInfoSP stop_info; + lldb::ThreadSP stop_thread; - Process::m_thread_list.SetSelectedThreadByID(m_active_exception->ThreadId); - stop_thread = Process::m_thread_list.GetSelectedThread(); - ArchSpec arch = GetArchitecture(); + Process::m_thread_list.SetSelectedThreadByID(exception_stream->ThreadId); + stop_thread = Process::m_thread_list.GetSelectedThread(); + ArchSpec arch = GetArchitecture(); - if (arch.GetTriple().getOS() == llvm::Triple::Linux) { - uint32_t signo = m_active_exception->ExceptionRecord.ExceptionCode; + if (arch.GetTriple().getOS() == llvm::Triple::Linux) { + uint32_t signo = exception_stream->ExceptionRecord.ExceptionCode; + if (signo == 0) { + // No stop. + return; + } - if (signo == 0) { - // No stop. - return; + stop_info = StopInfo::CreateStopReasonWithSignal(*stop_thread, signo); + } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { + stop_info = StopInfoMachException::CreateStopReasonWithMachException( + *stop_thread, exception_stream->ExceptionRecord.ExceptionCode, 2, + exception_stream->ExceptionRecord.ExceptionFlags, + exception_stream->ExceptionRecord.ExceptionAddress, 0); + } else { + std::string desc; + llvm::raw_string_ostream desc_stream(desc); + desc_stream << "Exception " + << llvm::format_hex( + exception_stream->ExceptionRecord.ExceptionCode, 8) + << " encountered at address " + << llvm::format_hex( + exception_stream->ExceptionRecord.ExceptionAddress, 8); + stop_info = StopInfo::CreateStopReasonWithException( + *stop_thread, desc_stream.str().c_str()); } - stop_info = StopInfo::CreateStopReasonWithSignal( - *stop_thread, signo); - } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { - stop_info = StopInfoMachException::CreateStopReasonWithMachException( - *stop_thread, m_active_exception->ExceptionRecord.ExceptionCode, 2, - m_active_exception->ExceptionRecord.ExceptionFlags, - m_active_exception->ExceptionRecord.ExceptionAddress, 0); - } else { - std::string desc; - llvm::raw_string_ostream desc_stream(desc); - desc_stream << "Exception " - << llvm::format_hex( - m_active_exception->ExceptionRecord.ExceptionCode, 8) - << " encountered at address " - << llvm::format_hex( - m_active_exception->ExceptionRecord.ExceptionAddress, 8); - stop_info = StopInfo::CreateStopReasonWithException( - *stop_thread, desc_stream.str().c_str()); - } - - stop_thread->SetStopInfo(stop_info); + stop_thread->SetStopInfo(stop_info); + } } bool ProcessMinidump::IsAlive() { return true; } @@ -387,10 +404,8 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list, LocationDescriptor context_location = thread.Context; // If the minidump contains an exception context, use it - if (m_active_exception != nullptr && - m_active_exception->ThreadId == thread.ThreadId) { - context_location = m_active_exception->ThreadContext; - } + if (m_exceptions_by_tid.count(thread.ThreadId) > 0) + context_location = m_exceptions_by_tid[thread.ThreadId]->ThreadContext; llvm::ArrayRef<uint8_t> context; if (!m_is_wow64) diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index e39ae3913e8782..7b7c970a38d4ec 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -107,7 +107,8 @@ class ProcessMinidump : public PostMortemProcess { private: lldb::DataBufferSP m_core_data; llvm::ArrayRef<minidump::Thread> m_thread_list; - const minidump::ExceptionStream *m_active_exception; + std::unordered_map<uint32_t, const minidump::ExceptionStream *> + m_exceptions_by_tid; lldb::CommandObjectSP m_command_sp; bool m_is_wow64; std::optional<MemoryRegionInfos> m_memory_regions; diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py index 2de3e36b507341..61a21309fa1835 100644 --- a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -510,3 +510,17 @@ def test_minidump_memory64list(self): self.assertTrue(region_info_list.GetMemoryRegionAtIndex(2, region)) self.assertEqual(region.GetRegionBase(), 0x00007fff12a87018) self.assertTrue(region.GetRegionEnd(), 0x00007fff12a87018 + 0x00000400) + + def test_multiple_exceptions_or_signals(self): + """Test that lldb can read the exception information from the Minidump.""" + print("Starting to read multiple-sigsev.yaml") + self.process_from_yaml("multiple-sigsev.yaml") + print("Done reading multiple-sigsev.yaml") + self.check_state() + # This process crashed due to a segmentation fault in both it's threads. + self.assertEqual(self.process.GetNumThreads(), 2) + for i in range(2): + thread = self.process.GetThreadAtIndex(i) + self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) + stop_description = thread.GetStopDescription(256) + self.assertIn("SIGSEGV", stop_description) diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/multiple-sigsev.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/multiple-sigsev.yaml new file mode 100644 index 00000000000000..f6fcfdbf5c0eb0 --- /dev/null +++ b/lldb/test/API/functionalities/postmortem/minidump-new/multiple-sigsev.yaml @@ -0,0 +1,39 @@ +--- !minidump +Streams: + - Type: ThreadList + Threads: + - Thread Id: 0x1B4F23 + Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Stack: + Start of Memory Range: 0x7FFFFFFFD348 + Content: '' + - Thread Id: 0x1B6D22 + Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Stack: + Start of Memory Range: 0x7FFFF75FDE28 + Content: '' + - Type: ModuleList + Modules: + - Base of Image: 0x0000000000400000 + Size of Image: 0x00017000 + Module Name: 'a.out' + CodeView Record: '' + - Type: SystemInfo + Processor Arch: AMD64 + Platform ID: Linux + CSD Version: 'Linux 3.13' + CPU: + Vendor ID: GenuineIntel + Version Info: 0x00000000 + Feature Info: 0x00000000 + - Type: Exception + Thread ID: 0x1B4F23 + Exception Record: + Exception Code: 0xB + Thread Context: 00000000 + - Type: Exception + Thread ID: 0x1B6D22 + Exception Record: + Exception Code: 0xB + Thread Context: 00000000 +... diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index 632a7fd4e4f8fa..c27fce80d67a13 100644 --- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -251,10 +251,11 @@ TEST_F(MinidumpParserTest, GetFilteredModuleList) { TEST_F(MinidumpParserTest, GetExceptionStream) { SetUpData("linux-x86_64.dmp"); - const llvm::minidump::ExceptionStream *exception_stream = - parser->GetExceptionStream(); - ASSERT_NE(nullptr, exception_stream); - ASSERT_EQ(11UL, exception_stream->ExceptionRecord.ExceptionCode); + std::optional<std::vector<const minidump::ExceptionStream *>> + exception_stream = parser->GetExceptionStreams(); + ASSERT_TRUE(exception_stream); + ASSERT_EQ(1UL, exception_stream->size()); + ASSERT_EQ(11UL, exception_stream->at(0)->ThreadId); } void check_mem_range_exists(MinidumpParser &parser, const uint64_t range_start, >From 9c90aa6466f050729637aed8bed3ee6c93374c4a Mon Sep 17 00:00:00 2001 From: Jacob Lalonde <jalalo...@fb.com> Date: Fri, 6 Sep 2024 13:33:36 -0700 Subject: [PATCH 2/4] Migrate code over to the new iterator api --- .../Process/minidump/MinidumpParser.cpp | 11 +--- .../Plugins/Process/minidump/MinidumpParser.h | 3 +- .../Process/minidump/ProcessMinidump.cpp | 53 +++++++++---------- .../Process/minidump/ProcessMinidump.h | 2 +- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index b0a6ed6e460daa..afc095ddbb2f91 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -417,16 +417,9 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() { return filtered_modules; } -std::optional<std::vector<const minidump::ExceptionStream *>> +llvm::iterator_range<ExceptionStreamsIterator> MinidumpParser::GetExceptionStreams() { - auto ExpectedStream = GetMinidumpFile().getExceptionStreams(); - if (ExpectedStream) - return ExpectedStream.get(); - - LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(), - "Failed to read minidump exception stream: {0}"); - - return std::nullopt; + return GetMinidumpFile().getExceptionStreams(); } std::optional<minidump::Range> diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index be6364ca6ecdc7..20f6d2a18989a1 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -48,6 +48,7 @@ struct Range { }; using FallibleMemory64Iterator = llvm::object::MinidumpFile::FallibleMemory64Iterator; +using ExceptionStreamsIterator = llvm::object::MinidumpFile::ExceptionStreamsIterator; class MinidumpParser { public: @@ -84,7 +85,7 @@ class MinidumpParser { // have the same name, it keeps the copy with the lowest load address. std::vector<const minidump::Module *> GetFilteredModuleList(); - std::optional<std::vector<const llvm::minidump::ExceptionStream *>> + llvm::iterator_range<ExceptionStreamsIterator> GetExceptionStreams(); std::optional<Range> FindMemoryRange(lldb::addr_t addr); diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index f876d666031c9a..67f3cfda9c9ecd 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -208,26 +208,21 @@ Status ProcessMinidump::DoLoadCore() { GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser->GetThreads(); - std::optional<std::vector<const minidump::ExceptionStream *>> - exception_streams = m_minidump_parser->GetExceptionStreams(); - - if (exception_streams) { - for (const auto *exception_stream : *exception_streams) { - if (!exception_stream) { - error.SetErrorString( - "Minidump returned null pointer for exception stream"); - return error; - } - if (!m_exceptions_by_tid - .try_emplace(exception_stream->ThreadId, exception_stream) - .second) { - // We only cast to avoid the warning around converting little endian in - // printf. - error.SetErrorStringWithFormat( - "Duplicate exception stream for tid %" PRIu32, - (uint32_t)exception_stream->ThreadId); - return error; - } + auto exception_stream_it = m_minidump_parser->GetExceptionStreams(); + for (auto exception_stream : exception_stream_it) { + // If we can't read an exception stream skip it + // We should probably serve a warning + if (!exception_stream) + continue; + + if (!m_exceptions_by_tid + .try_emplace(exception_stream->ThreadId, exception_stream.get()) + .second) { + // We only cast to avoid the warning around converting little endian in + // printf. + return Status::FromErrorStringWithFormat( + "Duplicate exception stream for tid %" PRIu32, + (uint32_t)exception_stream->ThreadId); } } @@ -254,7 +249,7 @@ void ProcessMinidump::RefreshStateAfterStop() { for (const auto &[_, exception_stream] : m_exceptions_by_tid) { constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF; - if (exception_stream->ExceptionRecord.ExceptionCode == + if (exception_stream.ExceptionRecord.ExceptionCode == BreakpadDumpRequested) { // This "ExceptionCode" value is a sentinel that is sometimes used // when generating a dump for a process that hasn't crashed. @@ -271,12 +266,12 @@ void ProcessMinidump::RefreshStateAfterStop() { lldb::StopInfoSP stop_info; lldb::ThreadSP stop_thread; - Process::m_thread_list.SetSelectedThreadByID(exception_stream->ThreadId); + Process::m_thread_list.SetSelectedThreadByID(exception_stream.ThreadId); stop_thread = Process::m_thread_list.GetSelectedThread(); ArchSpec arch = GetArchitecture(); if (arch.GetTriple().getOS() == llvm::Triple::Linux) { - uint32_t signo = exception_stream->ExceptionRecord.ExceptionCode; + uint32_t signo = exception_stream.ExceptionRecord.ExceptionCode; if (signo == 0) { // No stop. return; @@ -285,18 +280,18 @@ void ProcessMinidump::RefreshStateAfterStop() { stop_info = StopInfo::CreateStopReasonWithSignal(*stop_thread, signo); } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { stop_info = StopInfoMachException::CreateStopReasonWithMachException( - *stop_thread, exception_stream->ExceptionRecord.ExceptionCode, 2, - exception_stream->ExceptionRecord.ExceptionFlags, - exception_stream->ExceptionRecord.ExceptionAddress, 0); + *stop_thread, exception_stream.ExceptionRecord.ExceptionCode, 2, + exception_stream.ExceptionRecord.ExceptionFlags, + exception_stream.ExceptionRecord.ExceptionAddress, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); desc_stream << "Exception " << llvm::format_hex( - exception_stream->ExceptionRecord.ExceptionCode, 8) + exception_stream.ExceptionRecord.ExceptionCode, 8) << " encountered at address " << llvm::format_hex( - exception_stream->ExceptionRecord.ExceptionAddress, 8); + exception_stream.ExceptionRecord.ExceptionAddress, 8); stop_info = StopInfo::CreateStopReasonWithException( *stop_thread, desc_stream.str().c_str()); } @@ -405,7 +400,7 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list, // If the minidump contains an exception context, use it if (m_exceptions_by_tid.count(thread.ThreadId) > 0) - context_location = m_exceptions_by_tid[thread.ThreadId]->ThreadContext; + context_location = m_exceptions_by_tid[thread.ThreadId].ThreadContext; llvm::ArrayRef<uint8_t> context; if (!m_is_wow64) diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 7b7c970a38d4ec..f2ea0a2b61d14e 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -107,7 +107,7 @@ class ProcessMinidump : public PostMortemProcess { private: lldb::DataBufferSP m_core_data; llvm::ArrayRef<minidump::Thread> m_thread_list; - std::unordered_map<uint32_t, const minidump::ExceptionStream *> + std::unordered_map<uint32_t, const minidump::ExceptionStream> m_exceptions_by_tid; lldb::CommandObjectSP m_command_sp; bool m_is_wow64; >From bfb8f4f2f9becfd3156aefbcf1d34673abbcd8bd Mon Sep 17 00:00:00 2001 From: Jacob Lalonde <jalalo...@fb.com> Date: Fri, 6 Sep 2024 15:28:27 -0700 Subject: [PATCH 3/4] Edit tests --- .../Process/minidump/MinidumpParserTest.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index c27fce80d67a13..4e13a48cf11126 100644 --- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -251,11 +251,15 @@ TEST_F(MinidumpParserTest, GetFilteredModuleList) { TEST_F(MinidumpParserTest, GetExceptionStream) { SetUpData("linux-x86_64.dmp"); - std::optional<std::vector<const minidump::ExceptionStream *>> - exception_stream = parser->GetExceptionStreams(); - ASSERT_TRUE(exception_stream); - ASSERT_EQ(1UL, exception_stream->size()); - ASSERT_EQ(11UL, exception_stream->at(0)->ThreadId); + auto exception_streams = parser->GetExceptionStreams(); + size_t count = 0; + for (auto exception_stream : exception_streams) { + ASSERT_THAT_EXPECTED(exception_stream, llvm::Succeeded()); + ASSERT_EQ(16001UL, exception_stream->ThreadId); + count++; + } + + ASSERT_THAT(1UL, count); } void check_mem_range_exists(MinidumpParser &parser, const uint64_t range_start, >From 06e493fbd57cae1f2eb1240174d50a60d945a3de Mon Sep 17 00:00:00 2001 From: Jacob Lalonde <jalalo...@fb.com> Date: Fri, 6 Sep 2024 16:48:18 -0700 Subject: [PATCH 4/4] Run formatters --- lldb/source/Plugins/Process/minidump/MinidumpParser.h | 6 +++--- lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp | 4 ++-- .../postmortem/minidump-new/TestMiniDumpNew.py | 8 ++++---- lldb/unittests/Process/minidump/MinidumpParserTest.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 20f6d2a18989a1..f0b6e6027c52f0 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -48,7 +48,8 @@ struct Range { }; using FallibleMemory64Iterator = llvm::object::MinidumpFile::FallibleMemory64Iterator; -using ExceptionStreamsIterator = llvm::object::MinidumpFile::ExceptionStreamsIterator; +using ExceptionStreamsIterator = + llvm::object::MinidumpFile::ExceptionStreamsIterator; class MinidumpParser { public: @@ -85,8 +86,7 @@ class MinidumpParser { // have the same name, it keeps the copy with the lowest load address. std::vector<const minidump::Module *> GetFilteredModuleList(); - llvm::iterator_range<ExceptionStreamsIterator> - GetExceptionStreams(); + llvm::iterator_range<ExceptionStreamsIterator> GetExceptionStreams(); std::optional<Range> FindMemoryRange(lldb::addr_t addr); diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 67f3cfda9c9ecd..218012e656f07a 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -216,8 +216,8 @@ Status ProcessMinidump::DoLoadCore() { continue; if (!m_exceptions_by_tid - .try_emplace(exception_stream->ThreadId, exception_stream.get()) - .second) { + .try_emplace(exception_stream->ThreadId, exception_stream.get()) + .second) { // We only cast to avoid the warning around converting little endian in // printf. return Status::FromErrorStringWithFormat( diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py index 61a21309fa1835..5a0b6e790a424c 100644 --- a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -505,11 +505,11 @@ def test_minidump_memory64list(self): self.assertEqual(region.GetRegionBase(), 0x7FFF12A84030) self.assertTrue(region.GetRegionEnd(), 0x7FFF12A84030 + 0x2FD0) self.assertTrue(region_info_list.GetMemoryRegionAtIndex(1, region)) - self.assertEqual(region.GetRegionBase(), 0x00007fff12a87000) - self.assertTrue(region.GetRegionEnd(), 0x00007fff12a87000 + 0x00000018) + self.assertEqual(region.GetRegionBase(), 0x00007FFF12A87000) + self.assertTrue(region.GetRegionEnd(), 0x00007FFF12A87000 + 0x00000018) self.assertTrue(region_info_list.GetMemoryRegionAtIndex(2, region)) - self.assertEqual(region.GetRegionBase(), 0x00007fff12a87018) - self.assertTrue(region.GetRegionEnd(), 0x00007fff12a87018 + 0x00000400) + self.assertEqual(region.GetRegionBase(), 0x00007FFF12A87018) + self.assertTrue(region.GetRegionEnd(), 0x00007FFF12A87018 + 0x00000400) def test_multiple_exceptions_or_signals(self): """Test that lldb can read the exception information from the Minidump.""" diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index 4e13a48cf11126..c7547ba261c7f7 100644 --- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -258,7 +258,7 @@ TEST_F(MinidumpParserTest, GetExceptionStream) { ASSERT_EQ(16001UL, exception_stream->ThreadId); count++; } - + ASSERT_THAT(1UL, count); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits