[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Windows 0xEF Bugcheck Handler


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: "Durrant, Paul" <xadimgnik@xxxxxxxxx>
  • Date: Mon, 11 Dec 2023 16:21:08 +0000
  • Delivery-date: Mon, 11 Dec 2023 16:21:17 +0000
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

On 27/11/2023 11:16, Owen Smith wrote:
Adds a bugcheck handler for 0xEF (CRITICAL_PROCESS_DIED) which dumps the
process image file name (if available)
Adds ProcessGetImageFileName() to get the image file name, which relies
on calling MmGetSystemRoutineAddress("PsGetProcessImageFileName")

Suggested-by: Rabish Kumar <rabish.kumar@xxxxxxxxxx>
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>

Acked-by: Paul Durrant <paul@xxxxxxx>

---
  src/xen/bug_check.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
  src/xen/process.c   | 34 ++++++++++++++++++++++--
  src/xen/process.h   |  5 ++++
  3 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/src/xen/bug_check.c b/src/xen/bug_check.c
index e1da159..41b5f73 100644
--- a/src/xen/bug_check.c
+++ b/src/xen/bug_check.c
@@ -43,6 +43,7 @@
  #include "bug_check.h"
  #include "dbg_print.h"
  #include "assert.h"
+#include "process.h"
static KBUGCHECK_CALLBACK_RECORD BugCheckBugCheckCallbackRecord; @@ -1014,6 +1015,68 @@ BugCheckAssertionFailure(
      }
  }
+/// <summary>
+/// Bug check handler for critocal process died.
+/// 
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-check-0xef--critical-process-died
+/// </summary>
+/// <param name="Parameter1">process object.</param>
+/// <param name="Parameter2">If 0, a process terminated. If 1, a thread 
terminated.</param>
+/// <param name="Parameter3">reserved.</param>
+/// <param name="Parameter4">reserved.</param>
+static VOID
+BugCheckBugEFCriticalProcessDied(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        ULONG_PTR       Code = Parameter2;
+        CONTEXT         Context;
+
+        UNREFERENCED_PARAMETER(Parameter3);
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        switch (Code) {
+        case 0x0: {
+            PEPROCESS   EProcess = (PEPROCESS)Parameter1;
+            PCHAR       Name = ProcessGetImageFileName(EProcess);
+
+            if (Name == NULL)
+                Name = "(unknown)";
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: CRITICAL PROCESS: %p Name:%s DIED IRQL:%d 
\n",
+                      __MODULE__,
+                      EProcess,
+                      Name,
+                      KeGetCurrentIrql());
+            break;
+        }
+
+        case 0x1: {
+            PETHREAD    EThread = (PETHREAD)Parameter1;
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: CRITICAL THREAD: %p DIED IRQL:%d \n",
+                      __MODULE__,
+                      EThread,
+                      KeGetCurrentIrql());
+            break;
+        }
+
+        default:
+            break;
+        }
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
  struct _BUG_CODE_ENTRY {
      ULONG       Code;
      const CHAR  *Name;
@@ -1035,6 +1098,7 @@ struct _BUG_CODE_ENTRY   BugCodeTable[] = {
      DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, BugCheckInaccessibleBootDevice),
      DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, 
BugCheckDriverPowerStateFailure),
      DEFINE_HANDLER(ASSERTION_FAILURE, BugCheckAssertionFailure),
+    DEFINE_HANDLER(CRITICAL_PROCESS_DIED, BugCheckBugEFCriticalProcessDied),
      { 0, NULL, NULL }
  };
diff --git a/src/xen/process.c b/src/xen/process.c
index 4491196..2ba6599 100644
--- a/src/xen/process.c
+++ b/src/xen/process.c
@@ -40,8 +40,11 @@
  #include "dbg_print.h"
  #include "assert.h"
+typedef PCHAR (*GET_PROCESS_IMAGE_NAME)(PEPROCESS Process);
+
  typedef struct _PROCESS_CONTEXT {
-    LONG            References;
+    LONG                    References;
+    GET_PROCESS_IMAGE_NAME  PsGetProcFileName;
  } PROCESS_CONTEXT, *PPROCESS_CONTEXT;
static PROCESS_CONTEXT ProcessContext;
@@ -74,6 +77,24 @@ ProcessNotify(
      KeLowerIrql(Irql);
  }
+PCHAR
+ProcessGetImageFileName(
+    IN  PEPROCESS   Process
+    )
+{
+    PPROCESS_CONTEXT    Context = &ProcessContext;
+
+    if (Context->PsGetProcFileName == NULL)
+        goto fail1;
+
+    return Context->PsGetProcFileName(Process);
+
+fail1:
+    Error("Fail1 (process=%p)\n", Process);
+
+    return NULL;
+}
+
  VOID
  ProcessTeardown(
      VOID
@@ -81,6 +102,8 @@ ProcessTeardown(
  {
      PPROCESS_CONTEXT    Context = &ProcessContext;
+ Context->PsGetProcFileName = NULL;
+
      (VOID) PsSetCreateProcessNotifyRoutine(ProcessNotify, TRUE);
(VOID) InterlockedDecrement(&Context->References);
@@ -90,11 +113,12 @@ ProcessTeardown(
NTSTATUS
  ProcessInitialize(
-    VOID
+    VOID
      )
  {
      PPROCESS_CONTEXT    Context = &ProcessContext;
      ULONG               References;
+    UNICODE_STRING      Unicode;
      NTSTATUS            status;
References = InterlockedIncrement(&Context->References);
@@ -107,6 +131,12 @@ ProcessInitialize(
      if (!NT_SUCCESS(status))
          goto fail2;
+ RtlInitUnicodeString(&Unicode, L"PsGetProcessImageFileName");
+
+    Context->PsGetProcFileName = 
(GET_PROCESS_IMAGE_NAME)MmGetSystemRoutineAddress(&Unicode);
+    if (Context->PsGetProcFileName == NULL)
+        Warning("Unable to get PsGetProcessImageFileName Address\n");
+
      return STATUS_SUCCESS;
fail2:
diff --git a/src/xen/process.h b/src/xen/process.h
index 3b0233e..d25c8f0 100644
--- a/src/xen/process.h
+++ b/src/xen/process.h
@@ -44,4 +44,9 @@ ProcessTeardown(
      VOID
      );
+extern PCHAR
+ProcessGetImageFileName(
+    IN  PEPROCESS   Process
+    );
+
  #endif  // _XEN_PROCESS_H




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.