[Lldb-commits] [lldb] r245495 - Read exception records from Windows mini dump
Adrian McCarthy via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 19 13:43:23 PDT 2015
Author: amccarth
Date: Wed Aug 19 15:43:22 2015
New Revision: 245495
URL: http://llvm.org/viewvc/llvm-project?rev=245495&view=rev
Log:
Read exception records from Windows mini dump
Differential Revision: http://reviews.llvm.org/D12126
Modified:
lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.cpp
lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.h
Modified: lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h?rev=245495&r1=245494&r2=245495&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h Wed Aug 19 15:43:22 2015
@@ -14,6 +14,7 @@
#include "lldb/lldb-forward.h"
#include "lldb/Host/windows/windows.h"
+#include <DbgHelp.h>
#include <memory>
#include <vector>
@@ -40,6 +41,24 @@ class ExceptionRecord
m_thread_id = thread_id;
m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);
}
+
+ // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
+ ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id) :
+ m_code(record.ExceptionCode),
+ m_continuable(record.ExceptionFlags == 0),
+ m_next_exception(nullptr),
+ m_exception_addr(static_cast<lldb::addr_t>(record.ExceptionAddress)),
+ m_thread_id(thread_id),
+ m_arguments(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters)
+ {
+ // Set up link to nested exception.
+ if (record.ExceptionRecord)
+ {
+ m_next_exception.reset(new ExceptionRecord(*reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
+ thread_id));
+ }
+ }
+
virtual ~ExceptionRecord() {}
DWORD
Modified: lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.cpp?rev=245495&r1=245494&r2=245495&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.cpp (original)
+++ lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.cpp Wed Aug 19 15:43:22 2015
@@ -24,11 +24,15 @@
#include "lldb/Core/State.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/UnixSignals.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
+#include "../windows/ExceptionRecord.h" // TODO(amccarth): move this file to a common location
#include "ThreadWinMiniDump.h"
using namespace lldb_private;
@@ -45,6 +49,7 @@ public:
HANDLE m_dump_file; // handle to the open minidump file
HANDLE m_mapping; // handle to the file mapping for the minidump file
void * m_base_addr; // base memory address of the minidump
+ std::shared_ptr<ExceptionRecord> m_exception_sp;
};
ConstString
@@ -129,7 +134,8 @@ ProcessWinMiniDump::DoLoadCore()
m_target.SetArchitecture(DetermineArchitecture());
// TODO(amccarth): Build the module list.
- // TODO(amccarth): Read the exeception record.
+
+ ReadExceptionRecord();
return error;
@@ -146,21 +152,12 @@ ProcessWinMiniDump::GetDynamicLoader()
bool
ProcessWinMiniDump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- assert(m_data_up != nullptr);
- assert(m_data_up->m_base_addr != 0);
-
- MINIDUMP_DIRECTORY *dir = nullptr;
- void *ptr = nullptr;
- ULONG size = 0;
- if (::MiniDumpReadDumpStream(m_data_up->m_base_addr, ThreadListStream, &dir, &ptr, &size))
- {
- assert(dir->StreamType == ThreadListStream);
- assert(size == dir->Location.DataSize);
- assert(ptr == static_cast<void*>(static_cast<char*>(m_data_up->m_base_addr) + dir->Location.Rva));
- auto thread_list_ptr = static_cast<const MINIDUMP_THREAD_LIST *>(ptr);
+ size_t size = 0;
+ auto thread_list_ptr = static_cast<const MINIDUMP_THREAD_LIST *>(FindDumpStream(ThreadListStream, &size));
+ if (thread_list_ptr)
+ {
const ULONG32 thread_count = thread_list_ptr->NumberOfThreads;
- assert(thread_count < std::numeric_limits<int>::max());
- for (int i = 0; i < thread_count; ++i) {
+ for (ULONG32 i = 0; i < thread_count; ++i) {
std::shared_ptr<ThreadWinMiniDump> thread_sp(new ThreadWinMiniDump(*this, thread_list_ptr->Threads[i].ThreadId));
new_thread_list.AddThread(thread_sp);
}
@@ -172,6 +169,20 @@ ProcessWinMiniDump::UpdateThreadList(Thr
void
ProcessWinMiniDump::RefreshStateAfterStop()
{
+ if (!m_data_up) return;
+ if (!m_data_up->m_exception_sp) return;
+
+ auto active_exception = m_data_up->m_exception_sp;
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address "
+ << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+ m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
+ auto stop_thread = m_thread_list.GetSelectedThread();
+ auto stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
+ stop_thread->SetStopInfo(stop_info);
}
Error
@@ -302,18 +313,10 @@ ProcessWinMiniDump::MapMiniDumpIntoMemor
ArchSpec
ProcessWinMiniDump::DetermineArchitecture()
{
- assert(m_data_up != nullptr);
- assert(m_data_up->m_base_addr != 0);
-
- MINIDUMP_DIRECTORY *dir = nullptr;
- void *ptr = nullptr;
- ULONG size = 0;
- if (::MiniDumpReadDumpStream(m_data_up->m_base_addr, SystemInfoStream, &dir, &ptr, &size))
- {
- assert(dir->StreamType == SystemInfoStream);
- assert(size == dir->Location.DataSize);
- assert(ptr == static_cast<void*>(static_cast<char*>(m_data_up->m_base_addr) + dir->Location.Rva));
- auto system_info_ptr = static_cast<const MINIDUMP_SYSTEM_INFO *>(ptr);
+ size_t size = 0;
+ auto system_info_ptr = static_cast<const MINIDUMP_SYSTEM_INFO *>(FindDumpStream(SystemInfoStream, &size));
+ if (system_info_ptr)
+ {
switch (system_info_ptr->ProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_INTEL:
@@ -327,3 +330,33 @@ ProcessWinMiniDump::DetermineArchitectur
return ArchSpec(); // invalid or unknown
}
+
+void
+ProcessWinMiniDump::ReadExceptionRecord() {
+ size_t size = 0;
+ auto exception_stream_ptr = static_cast<MINIDUMP_EXCEPTION_STREAM*>(FindDumpStream(ExceptionStream, &size));
+ if (exception_stream_ptr)
+ {
+ m_data_up->m_exception_sp.reset(new ExceptionRecord(exception_stream_ptr->ExceptionRecord, exception_stream_ptr->ThreadId));
+ }
+}
+
+void *
+ProcessWinMiniDump::FindDumpStream(unsigned stream_number, size_t *size_out) {
+ void *stream = nullptr;
+ *size_out = 0;
+
+ assert(m_data_up != nullptr);
+ assert(m_data_up->m_base_addr != 0);
+
+ MINIDUMP_DIRECTORY *dir = nullptr;
+ if (::MiniDumpReadDumpStream(m_data_up->m_base_addr, stream_number, &dir, nullptr, nullptr) &&
+ dir != nullptr && dir->Location.DataSize > 0)
+ {
+ assert(dir->StreamType == stream_number);
+ *size_out = dir->Location.DataSize;
+ stream = static_cast<void*>(static_cast<char*>(m_data_up->m_base_addr) + dir->Location.Rva);
+ }
+
+ return stream;
+}
Modified: lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.h?rev=245495&r1=245494&r2=245495&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.h (original)
+++ lldb/trunk/source/Plugins/Process/win-minidump/ProcessWinMiniDump.h Wed Aug 19 15:43:22 2015
@@ -97,6 +97,15 @@ private:
lldb_private::ArchSpec
DetermineArchitecture();
+ void
+ ReadExceptionRecord();
+
+ // A thin wrapper around WinAPI's MiniDumpReadDumpStream to avoid redundant
+ // checks. If there's a failure (e.g., if the requested stream doesn't exist),
+ // the function returns nullptr and sets *size_out to 0.
+ void *
+ FindDumpStream(unsigned stream_number, size_t *size_out);
+
// Isolate the data to keep Windows-specific types out of this header. Can't
// use the typical pimpl idiom because the implementation of this class also
// needs access to public and protected members of the base class.
More information about the lldb-commits
mailing list