[Lldb-commits] [lldb] r359420 - [Windows] Dump more information about access violation exception

Aleksandr Urakov via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 29 00:29:25 PDT 2019


Author: aleksandr.urakov
Date: Mon Apr 29 00:29:25 2019
New Revision: 359420

URL: http://llvm.org/viewvc/llvm-project?rev=359420&view=rev
Log:
[Windows] Dump more information about access violation exception

Summary:
Dump more information about "access violation" and "in page error" exceptions to
description. Description now contains data about read/write violation type and
actual address as described at
https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record

Reviewers: asmith, stella.stamenova

Reviewed By: stella.stamenova

Subscribers: teemperor, amccarth, abidh, lldb-commits, aleksandr.urakov

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D60519

Added:
    lldb/trunk/lit/Process/
    lldb/trunk/lit/Process/Windows/
    lldb/trunk/lit/Process/Windows/exception_access_violation.cpp
Modified:
    lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
    lldb/trunk/source/Plugins/Process/Windows/Common/ExceptionRecord.h
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp

Added: lldb/trunk/lit/Process/Windows/exception_access_violation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Process/Windows/exception_access_violation.cpp?rev=359420&view=auto
==============================================================================
--- lldb/trunk/lit/Process/Windows/exception_access_violation.cpp (added)
+++ lldb/trunk/lit/Process/Windows/exception_access_violation.cpp Mon Apr 29 00:29:25 2019
@@ -0,0 +1,37 @@
+// clang-format off
+
+// REQUIRES: system-windows
+// RUN: %build --compiler=clang-cl -o %t.exe -- %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -o "run" -- write | FileCheck --check-prefix=WRITE %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -o "run" -- read | FileCheck --check-prefix=READ %s
+
+#include <string.h>
+
+int access_violation_write(void* addr) {
+    *(int*)addr = 42;
+    return 0;
+}
+
+
+int access_violation_read(void* addr) {
+    volatile int ret = *(int*)addr;
+    return ret;
+}
+
+int main(int argc, char *argv[]) {
+    if (argc < 2) {
+        return 1;
+    }
+    if (strcmp(argv[1], "write") == 0) {
+        return access_violation_write((void*)42);
+    }
+    if (strcmp(argv[1], "read") == 0) {
+        return access_violation_read((void*)42);
+    }
+    return 1;
+}
+
+
+// WRITE:     * thread #1, stop reason = Exception 0xc0000005 encountered at address {{.*}}: Access violation writing location 0x0000002a
+
+// READ:      * thread #1, stop reason = Exception 0xc0000005 encountered at address {{.*}}: Access violation reading location 0x0000002a

Modified: lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py?rev=359420&r1=359419&r2=359420&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lldbutil.py Mon Apr 29 00:29:25 2019
@@ -737,7 +737,7 @@ def is_thread_crashed(test, thread):
         return thread.GetStopReason() == lldb.eStopReasonSignal and thread.GetStopReasonDataAtIndex(
             0) == thread.GetProcess().GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
     elif test.getPlatform() == "windows":
-        return "Exception 0xc0000005" in thread.GetStopDescription(100)
+        return "Exception 0xc0000005" in thread.GetStopDescription(200)
     else:
         return "invalid address" in thread.GetStopDescription(100)
 

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ExceptionRecord.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ExceptionRecord.h?rev=359420&r1=359419&r2=359420&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ExceptionRecord.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ExceptionRecord.h Mon Apr 29 00:29:25 2019
@@ -64,6 +64,8 @@ public:
 
   lldb::tid_t GetThreadID() const { return m_thread_id; }
 
+  const std::vector<ULONG_PTR>& GetExceptionArguments() const { return m_arguments; }
+
 private:
   DWORD m_code;
   bool m_continuable;

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=359420&r1=359419&r2=359420&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp Mon Apr 29 00:29:25 2019
@@ -474,6 +474,74 @@ void ProcessWindows::DidAttach(ArchSpec
     RefreshStateAfterStop();
 }
 
+static void
+DumpAdditionalExceptionInformation(llvm::raw_ostream &stream,
+                                   const ExceptionRecordSP &exception) {
+  // Decode additional exception information for specific exception types based
+  // on
+  // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record
+
+  const int addr_min_width = 2 + 8; // "0x" + 4 address bytes
+
+  const std::vector<ULONG_PTR> &args = exception->GetExceptionArguments();
+  switch (exception->GetExceptionCode()) {
+  case EXCEPTION_ACCESS_VIOLATION: {
+    if (args.size() < 2)
+      break;
+
+    stream << ": ";
+    const int access_violation_code = args[0];
+    const lldb::addr_t access_violation_address = args[1];
+    switch (access_violation_code) {
+    case 0:
+      stream << "Access violation reading";
+      break;
+    case 1:
+      stream << "Access violation writing";
+      break;
+    case 8:
+      stream << "User-mode data execution prevention (DEP) violation at";
+      break;
+    default:
+      stream << "Unknown access violation (code " << access_violation_code
+             << ") at";
+      break;
+    }
+    stream << " location "
+           << llvm::format_hex(access_violation_address, addr_min_width);
+    break;
+  }
+  case EXCEPTION_IN_PAGE_ERROR: {
+    if (args.size() < 3)
+      break;
+
+    stream << ": ";
+    const int page_load_error_code = args[0];
+    const lldb::addr_t page_load_error_address = args[1];
+    const DWORD underlying_code = args[2];
+    switch (page_load_error_code) {
+    case 0:
+      stream << "In page error reading";
+      break;
+    case 1:
+      stream << "In page error writing";
+      break;
+    case 8:
+      stream << "User-mode data execution prevention (DEP) violation at";
+      break;
+    default:
+      stream << "Unknown page loading error (code " << page_load_error_code
+             << ") at";
+      break;
+    }
+    stream << " location "
+           << llvm::format_hex(page_load_error_address, addr_min_width)
+           << " (status code " << llvm::format_hex(underlying_code, 8) << ")";
+    break;
+  }
+  }
+}
+
 void ProcessWindows::RefreshStateAfterStop() {
   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
   llvm::sys::ScopedLock lock(m_mutex);
@@ -573,6 +641,8 @@ void ProcessWindows::RefreshStateAfterSt
                 << llvm::format_hex(active_exception->GetExceptionCode(), 8)
                 << " encountered at address "
                 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+    DumpAdditionalExceptionInformation(desc_stream, active_exception);
+
     stop_info = StopInfo::CreateStopReasonWithException(
         *stop_thread, desc_stream.str().c_str());
     stop_thread->SetStopInfo(stop_info);




More information about the lldb-commits mailing list