]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Windows 0xEF Bugcheck Handler
authorOwen Smith <owen.smith@cloud.com>
Mon, 27 Nov 2023 11:16:11 +0000 (11:16 +0000)
committerPaul Durrant <pdurrant@amazon.com>
Mon, 11 Dec 2023 16:22:49 +0000 (16:22 +0000)
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@citrix.com>
Signed-off-by: Owen Smith <owen.smith@cloud.com>
src/xen/bug_check.c
src/xen/process.c
src/xen/process.h

index e1da1597ea242744be83524d378f8a89048cce37..41b5f7319e1edb5e8dd4fe64877f69ff69d47707 100644 (file)
@@ -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 }
 };
 
index 44911963c9d86d7676369c2902fa7b9f53f117e2..2ba65998f5175b3b8b258ea00e6a9fa4674836bf 100644 (file)
 #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:
index 3b0233ede22e7ca268e1f68072c48505f37e9fd0..d25c8f02cff0d9ade7cdfe2592d1998519f7c7ab 100644 (file)
@@ -44,4 +44,9 @@ ProcessTeardown(
     VOID
     );
 
+extern PCHAR
+ProcessGetImageFileName(
+    IN  PEPROCESS   Process
+    );
+
 #endif  // _XEN_PROCESS_H