Index: source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp =================================================================== --- source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp +++ source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp @@ -39,7 +39,8 @@ return false; } HANDLE file_handle = ::CreateFileW(wide_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - const auto result = ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle, MiniDumpNormal, NULL, NULL, NULL); + const auto result = ::MiniDumpWriteDump(process_handle, process_sp->GetID(), file_handle, + MiniDumpWithFullMemoryInfo, NULL, NULL, NULL); ::CloseHandle(file_handle); ::CloseHandle(process_handle); if (!result) Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h =================================================================== --- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h +++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h @@ -84,7 +84,10 @@ lldb_private::ArchSpec GetArchitecture(); -protected: + lldb_private::Error GetMemoryRegionInfo(lldb::addr_t load_addr, + lldb_private::MemoryRegionInfo &range_info) override; + + protected: void Clear(); Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp =================================================================== --- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp +++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp @@ -17,21 +17,22 @@ #include #include -#include "lldb/Core/PluginManager.h" +#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" #include "lldb/Core/State.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" -#include "lldb/Target/DynamicLoader.h" #include "lldb/Target/UnixSignals.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/ConvertUTF.h" -#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h" #include "ExceptionRecord.h" #include "ThreadWinMiniDump.h" @@ -272,6 +273,61 @@ return overlap; } +Error +ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info) +{ + Error error; + size_t size; + const auto list = reinterpret_cast(FindDumpStream(MemoryInfoListStream, &size)); + if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST)) + { + error.SetErrorString("the mini dump contains no memory range information"); + return error; + } + + if (list->SizeOfEntry < sizeof(MINIDUMP_MEMORY_INFO)) + { + error.SetErrorString("the entries in the mini dump memory info list are smaller than expected"); + return error; + } + + if (size < list->SizeOfHeader + list->SizeOfEntry * list->NumberOfEntries) + { + error.SetErrorString("the mini dump memory info list is incomplete"); + return error; + } + + for (int i = 0; i < list->NumberOfEntries; ++i) + { + const auto entry = reinterpret_cast(reinterpret_cast(list) + + list->SizeOfHeader + i * list->SizeOfEntry); + const auto head = entry->BaseAddress; + const auto tail = head + entry->RegionSize; + if (head <= load_addr && load_addr < tail) + { + // The Windows page protection bits are not independent masks that can + // be bitwise-ORed together. For example, PAGE_EXECUTE_READ is not + // (PAGE_EXECUTE | PAGE_READ). To test for an access type, it's + // necessary to test for any of the bits that provide that access type. + const bool readable = + entry->Protect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READONLY | PAGE_READWRITE); + info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); + const bool writable = + entry->Protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY); + info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); + const bool executable = + entry->Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); + info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); + return error; + } + } + // Note that the memory info list doesn't seem to contain ranges in kernel space, + // so if you're walking a stack that has kernel frames, the stack may appear + // truncated. + error.SetErrorString("address is not in a known range"); + return error; +} + void ProcessWinMiniDump::Clear() {