[Lldb-commits] [PATCH] D15218: Implement GetMemoryRegionInfo for mini dumps.

Adrian McCarthy via lldb-commits lldb-commits at lists.llvm.org
Thu Dec 3 16:18:16 PST 2015


amccarth created this revision.
amccarth added a reviewer: zturner.
amccarth added a subscriber: lldb-commits.

Also tweaked process save-core to include the memory info list so that we can see the regions in the list.

There are no commands or SBInterfaces yet that make it possible to test this directly, but I'll look for an opportunity to do so as I continue to work toward working backtraces from mini dumps.

http://reviews.llvm.org/D15218

Files:
  source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
  source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
  source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h

Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
===================================================================
--- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
+++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
@@ -84,6 +84,9 @@
     lldb_private::ArchSpec
     GetArchitecture();
 
+    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
@@ -27,6 +27,7 @@
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/UnixSignals.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
@@ -272,6 +273,60 @@
     return overlap;
 }
 
+
+Error
+ProcessWinMiniDump::GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &info)
+{
+    Error error;
+    size_t size;
+    const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(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;
+    }
+
+    const auto entries = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(list) + list->SizeOfHeader);
+
+    for (int i = 0; i < list->NumberOfEntries; ++i)
+    {
+        const auto entry = reinterpret_cast<const MINIDUMP_MEMORY_INFO *>(reinterpret_cast<const char *>(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()
 {
Index: source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
===================================================================
--- source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
+++ source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
@@ -39,7 +39,7 @@
         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)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15218.41824.patch
Type: text/x-patch
Size: 4644 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20151204/0a219eb3/attachment-0001.bin>


More information about the lldb-commits mailing list