hhellyer updated this revision to Diff 63975.
hhellyer added a comment.

.arcconfig has been updated.


https://reviews.llvm.org/D22352

Files:
  source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
  source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp

Index: source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
===================================================================
--- source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
+++ source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
@@ -277,6 +277,7 @@
 {
     Error error;
     size_t size;
+    info.Clear();
     const auto list = reinterpret_cast<const MINIDUMP_MEMORY_INFO_LIST *>(FindDumpStream(MemoryInfoListStream, &size));
     if (list == nullptr || size < sizeof(MINIDUMP_MEMORY_INFO_LIST))
     {
@@ -296,24 +297,44 @@
         return error;
     }
 
+    const MINIDUMP_MEMORY_INFO *next_entry = nullptr;
+
     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.GetRange().SetRangeBase((entry->State != MEM_FREE) ? head : load_addr);
+            info.GetRange().SetRangeEnd(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);
+            info.SetMapped((entry->State != MEM_FREE) ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
             return error;
         }
+        else if (head > load_addr && (next_entry == nullptr || head < next_entry->BaseAddress) )
+        {
+            // In case there is no region containing load_addr keep track of the nearest region
+            // after load_addr so we can return the distance to it.
+            next_entry = entry;
+        }
     }
+
+    // No containing region found. Create an unmapped region that extends to the next region
+    // or LLDB_INVALID_ADDRESS
+    info.GetRange().SetRangeBase(load_addr);
+    info.GetRange().SetRangeEnd((next_entry != nullptr)?next_entry->BaseAddress:LLDB_INVALID_ADDRESS);
+    info.SetReadable(MemoryRegionInfo::eNo);
+    info.SetWritable(MemoryRegionInfo::eNo);
+    info.SetExecutable(MemoryRegionInfo::eNo);
+    info.SetMapped(MemoryRegionInfo::eNo);
+
     // 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;
 }
 
Index: source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
===================================================================
--- source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
+++ source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
@@ -748,14 +748,14 @@
 {
     Error error;
     llvm::sys::ScopedLock lock(m_mutex);
+    info.Clear();
 
     if (!m_session_data)
     {
         error.SetErrorString("GetMemoryRegionInfo called with no debugging session.");
         WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
         return error;
     }
-
     HostProcess process = m_session_data->m_debugger->GetProcess();
     lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
     if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
@@ -772,22 +772,67 @@
     SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
     if (result == 0)
     {
-        error.SetError(::GetLastError(), eErrorTypeWin32);
-        WINERR_IFALL(WINDOWS_LOG_MEMORY,
-                     "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
-                     error.GetError(), vm_addr);
-        return error;
+        if (::GetLastError() == ERROR_INVALID_PARAMETER)
+        {
+            // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an address
+            // past the highest accessible address. We should return a range from the vm_addr
+            // to LLDB_INVALID_ADDRESS
+            info.GetRange().SetRangeBase(vm_addr);
+            info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+            info.SetReadable(MemoryRegionInfo::eNo);
+            info.SetExecutable(MemoryRegionInfo::eNo);
+            info.SetWritable(MemoryRegionInfo::eNo);
+            info.SetMapped(MemoryRegionInfo::eNo);
+            return error;
+        }
+        else
+        {
+            error.SetError(::GetLastError(), eErrorTypeWin32);
+            WINERR_IFALL(WINDOWS_LOG_MEMORY,
+                    "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
+                    error.GetError(), vm_addr);
+            return error;
+        }
+    }
+
+    // Protect bits are only valid for MEM_COMMIT regions.
+    if (mem_info.State == MEM_COMMIT) {
+        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);
+    }
+    else
+    {
+        info.SetReadable(MemoryRegionInfo::eNo);
+        info.SetExecutable(MemoryRegionInfo::eNo);
+        info.SetWritable(MemoryRegionInfo::eNo);
+    }
+
+    // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
+    if (mem_info.State != MEM_FREE) {
+        info.GetRange().SetRangeBase(reinterpret_cast<addr_t>(mem_info.AllocationBase));
+        info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + mem_info.RegionSize);
+        info.SetMapped(MemoryRegionInfo::eYes);
+    }
+    else
+    {
+        // In the unmapped case we need to return the distance to the next block of memory.
+        // VirtualQueryEx nearly does that except that it gives the distance from the start
+        // of the page containing vm_addr.
+        SYSTEM_INFO data;
+        GetSystemInfo(&data);
+        DWORD page_offset = vm_addr % data.dwPageSize;
+        info.GetRange().SetRangeBase(vm_addr);
+        info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
+        info.SetMapped(MemoryRegionInfo::eNo);
     }
-    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));
+                  BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
     return error;
 }
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to