[Lldb-commits] [lldb] r254780 - Implement GetMemoryRegionInfo for mini dumps.

Adrian McCarthy via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 4 14:22:15 PST 2015


Author: amccarth
Date: Fri Dec  4 16:22:15 2015
New Revision: 254780

URL: http://llvm.org/viewvc/llvm-project?rev=254780&view=rev
Log:
Implement GetMemoryRegionInfo for mini dumps.

Differential Revision: http://reviews.llvm.org/D15218

Modified:
    lldb/trunk/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h
    lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
    lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
    lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h

Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp Fri Dec  4 16:22:15 2015
@@ -39,7 +39,8 @@ SaveMiniDump(const lldb::ProcessSP &proc
         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)

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp Fri Dec  4 16:22:15 2015
@@ -15,6 +15,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
+#include "lldb/Host/windows/windows.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Target.h"
@@ -74,4 +75,26 @@ ProcessWindows::GetImageInfoAddress()
         return LLDB_INVALID_ADDRESS;
 }
 
+// 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.
+bool
+ProcessWindows::IsPageReadable(uint32_t protect)
+{
+    return (protect & PAGE_NOACCESS) == 0;
+}
+
+bool
+ProcessWindows::IsPageWritable(uint32_t protect)
+{
+    return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
+}
+
+bool
+ProcessWindows::IsPageExecutable(uint32_t protect)
+{
+    return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0;
+}
+
 }

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h Fri Dec  4 16:22:15 2015
@@ -34,6 +34,17 @@ public:
     size_t PutSTDIN(const char *buf, size_t buf_size, lldb_private::Error &error) override;
 
     lldb::addr_t GetImageInfoAddress() override;
+
+protected:
+    // These decode the page protection bits.
+    static bool
+    IsPageReadable(uint32_t protect);
+
+    static bool
+    IsPageWritable(uint32_t protect);
+
+    static bool
+    IsPageExecutable(uint32_t protect);
 };
 
 }

Modified: lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp Fri Dec  4 16:22:15 2015
@@ -743,12 +743,13 @@ ProcessWindowsLive::GetMemoryRegionInfo(
                      error.GetError(), vm_addr);
         return error;
     }
-    bool readable = !(mem_info.Protect & PAGE_NOACCESS);
-    bool executable = mem_info.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
-    bool writable = mem_info.Protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY);
+    const bool readable = IsPageReadable(mem_info.Protect);
+    const bool executable = IsPageExecutable(mem_info.Protect);
+    const bool writable = IsPageWritable(mem_info.Protect);
     info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
     info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
     info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+
     error.SetError(::GetLastError(), eErrorTypeWin32);
     WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
                   BOOL_STR(readable), BOOL_STR(executable), BOOL_STR(writable));

Modified: lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp Fri Dec  4 16:22:15 2015
@@ -17,21 +17,22 @@
 #include <memory>
 #include <mutex>
 
-#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,51 @@ ProcessWinMiniDump::DoReadMemory(lldb::a
     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;
+    }
+
+    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)
+        {
+            info.SetReadable(IsPageReadable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+            info.SetWritable(IsPageWritable(entry->Protect) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+            info.SetExecutable(IsPageExecutable(entry->Protect) ? 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()
 {

Modified: lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h?rev=254780&r1=254779&r2=254780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h Fri Dec  4 16:22:15 2015
@@ -23,7 +23,7 @@ struct ThreadData;
 
 class ProcessWinMiniDump : public lldb_private::ProcessWindows
 {
-public:
+  public:
     static lldb::ProcessSP
     CreateInstance (lldb::TargetSP target_sp,
                     lldb_private::Listener &listener,
@@ -84,7 +84,10 @@ public:
     lldb_private::ArchSpec
     GetArchitecture();
 
-protected:
+    lldb_private::Error
+    GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &range_info) override;
+
+  protected:
     void
     Clear();
 
@@ -92,7 +95,7 @@ protected:
     UpdateThreadList(lldb_private::ThreadList &old_thread_list,
                      lldb_private::ThreadList &new_thread_list) override;
 
-private:
+  private:
     // Describes a range of memory captured in the mini dump.
     struct Range {
       lldb::addr_t start;  // virtual address of the beginning of the range




More information about the lldb-commits mailing list