[debug] Rename Debug_Initialize(), register bug-check...
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sun, 23 Jan 2011 17:00:27 +0000 (12:00 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Sun, 23 Jan 2011 17:00:27 +0000 (12:00 -0500)
...call-back routine to display evidence of life.

We also save the last DBG() message (minus variable args)
in a global so that we can observe it from WinDbg.  Why?
QEmu (on Windows)'s serial feature seems to limit us with
WinDbg...  If the Windows kernel doesn't speak to WinDbg
very soon, or apparently if the keyboard has been polled,
QEmu doesn't seem to establish the WinDbg connection until
an actual bug-check.  That means we can't see any DBG()
messages at all, which is highly annoying.  At least we
can now inspect the most recent DBG() message. *sigh*

src/include/debug.h
src/winvblock/debug.c
src/winvblock/driver.c

index 348ec77..d565698 100644 (file)
     WvlDebugPrint(                  \
         __FILE__,                   \
         (const PCHAR) __FUNCTION__, \
-        __LINE__                    \
+        __LINE__,                   \
+        __VA_ARGS__                 \
       ),                            \
     DbgPrint(__VA_ARGS__)           \
   )
-extern WVL_M_LIB NTSTATUS STDCALL WvlDebugPrint(IN PCHAR, IN PCHAR, IN UINT32);
+extern WVL_M_LIB NTSTATUS STDCALL WvlDebugPrint(
+    IN PCHAR,
+    IN PCHAR,
+    IN UINT32,
+    IN PCHAR,
+    ...
+  );
 #else
 #  define DBG(...) ((VOID) 0)
 #endif
@@ -80,7 +87,8 @@ extern VOID STDCALL WvlDebugIrpEnd(IN PIRP, IN NTSTATUS);
 #  define WVL_M_DEBUG_IRP_END(Irp_, Status_) ((VOID) 0)
 #endif
 
-extern VOID Debug_Initialize(void);
+extern VOID WvlDebugModuleInit(void);
+extern VOID WvlDebugModuleUnload(void);
 extern WVL_M_LIB NTSTATUS STDCALL WvlError(IN PCHAR, IN NTSTATUS);
 
 #endif  /* WVL_M_DEBUG_H_ */
index 2660d81..1d40bdc 100644 (file)
 #include "aoe.h"
 #include "debug.h"
 
-static KSPIN_LOCK Debug_Globals_SpinLock;
+/* Private objects. */
+static KSPIN_LOCK WvlDebugLock_;
+#if WVL_M_DEBUG
+static KBUGCHECK_CALLBACK_RECORD WvlDebugBugCheckRecord_;
+static PCHAR WvlDebugLastMsg_ = NULL;
+static BOOLEAN WvlDebugBugCheckRegistered_ = FALSE;
+#endif
+
+/* Private function declarations. */
+#if WVL_M_DEBUG
+/* Why is KBUGCHECK_CALLBACK_ROUTINE missing? */
+static VOID WvlDebugBugCheck_(PVOID, ULONG);
+#endif
 
 #if WVL_M_DEBUG
 WVL_M_LIB NTSTATUS STDCALL WvlDebugPrint(
     IN PCHAR File,
     IN PCHAR Function,
-    IN UINT32 Line
+    IN UINT32 Line,
+    IN PCHAR Message,
+    ...
   ) {
     #if WVL_M_DEBUG_FILE
     DbgPrint(File);
@@ -62,13 +76,35 @@ WVL_M_LIB NTSTATUS STDCALL WvlDebugPrint(
     #if WVL_M_DEBUG_THREAD
     DbgPrint("T[%p]: ", (PVOID) PsGetCurrentThread());
     #endif
+    WvlDebugLastMsg_ = Message;
     return DbgPrint("%s(): ", Function);
   }
 #endif
 
-VOID Debug_Initialize(void) {
-  KeInitializeSpinLock ( &Debug_Globals_SpinLock );
-}
+VOID WvlDebugModuleInit(void) {
+    KeInitializeSpinLock(&WvlDebugLock_);
+    #if WVL_M_DEBUG
+    KeInitializeCallbackRecord(&WvlDebugBugCheckRecord_);
+    WvlDebugBugCheckRegistered_ = KeRegisterBugCheckCallback(
+        &WvlDebugBugCheckRecord_,
+        WvlDebugBugCheck_,
+        &WvlDebugLastMsg_,
+        sizeof WvlDebugLastMsg_,
+        WVL_M_LIT
+      );
+    if (!WvlDebugBugCheckRegistered_)
+      DBG("Couldn't register bug-check callback!\n");
+    #endif
+    return;
+  }
+
+VOID WvlDebugModuleUnload(void) {
+    #if WVL_M_DEBUG
+    if (WvlDebugBugCheckRegistered_)
+      KeDeregisterBugCheckCallback(&WvlDebugBugCheckRecord_);
+    #endif
+    return;
+  }
 
 WVL_M_LIB NTSTATUS STDCALL WvlError(
     IN PCHAR Message,
@@ -140,11 +176,11 @@ Debug_IrpListRecord (
   PDEBUG_IRPLIST Record;
   KIRQL Irql;
 
-  KeAcquireSpinLock ( &Debug_Globals_SpinLock, &Irql );
+  KeAcquireSpinLock(&WvlDebugLock_, &Irql);
   Record = Debug_Globals_IrpList;
   while ( Record != NULL && Record->Irp != Irp )
     Record = Record->Next;
-  KeReleaseSpinLock ( &Debug_Globals_SpinLock, Irql );
+  KeReleaseSpinLock(&WvlDebugLock_, Irql);
   return Record;
 }
 
@@ -170,7 +206,7 @@ WVL_M_LIB VOID STDCALL WvlDebugIrpStart(
   Record->Irp = Irp;
   Record->DebugMessage = DebugMessage;
   Record->Number = InterlockedIncrement ( &Debug_Globals_Number );;
-  KeAcquireSpinLock ( &Debug_Globals_SpinLock, &Irql );
+  KeAcquireSpinLock(&WvlDebugLock_, &Irql);
   if ( Debug_Globals_IrpList == NULL )
     {
       Debug_Globals_IrpList = Record;
@@ -184,7 +220,7 @@ WVL_M_LIB VOID STDCALL WvlDebugIrpStart(
       Temp->Next = Record;
       Record->Previous = Temp;
     }
-  KeReleaseSpinLock ( &Debug_Globals_SpinLock, Irql );
+  KeReleaseSpinLock(&WvlDebugLock_, Irql);
   DBG ( "IRP %d: %s\n", Record->Number, Record->DebugMessage );
 }
 
@@ -203,7 +239,7 @@ VOID STDCALL WvlDebugIrpEnd(IN PIRP Irp, IN NTSTATUS Status) {
    * Debug_Globals_IrpList, unless WvlDebugIrpEnd is called more than once on
    * an irp (which itself is a bug, it should only be called one time).
    */
-  KeAcquireSpinLock ( &Debug_Globals_SpinLock, &Irql );
+  KeAcquireSpinLock(&WvlDebugLock_, &Irql);
   if ( Record->Previous == NULL )
     {
       Debug_Globals_IrpList = Record->Next;
@@ -216,7 +252,7 @@ VOID STDCALL WvlDebugIrpEnd(IN PIRP Irp, IN NTSTATUS Status) {
     {
       Record->Next->Previous = Record->Previous;
     }
-  KeReleaseSpinLock ( &Debug_Globals_SpinLock, Irql );
+  KeReleaseSpinLock(&WvlDebugLock_, Irql);
 
   DBG ( "IRP %d: %s -> 0x%08x\n", Record->Number, Record->DebugMessage,
        Status );
@@ -828,3 +864,17 @@ Debug_SCSIOPString (
     }
 }
 #endif  /* WVL_M_DEBUG && WVL_M_DEBUG_IRPS */
+
+#if WVL_M_DEBUG
+static VOID WvlDebugBugCheck_(PVOID buf, ULONG len) {
+    static WCHAR wv_string[] = WVL_M_WLIT L": Alive\n";
+    static UNICODE_STRING wv_ustring = {
+        sizeof wv_string,
+        sizeof wv_string,
+        wv_string
+      };
+
+    ZwDisplayString(&wv_ustring);
+    return;
+  }
+#endif
index b38bcfc..81220bf 100644 (file)
@@ -156,10 +156,12 @@ NTSTATUS STDCALL DriverEntry(
     WvDriverObj = DriverObject;
     if (WvDriverStarted)
       return STATUS_SUCCESS;
-    Debug_Initialize();
+    WvlDebugModuleInit();
     status = WvlRegNoteOsLoadOpts(&WvOsLoadOpts);
-    if (!NT_SUCCESS(status))
-      return WvlError("WvlRegNoteOsLoadOpts", status);
+    if (!NT_SUCCESS(status)) {
+        WvlDebugModuleUnload();
+        return WvlError("WvlRegNoteOsLoadOpts", status);
+      }
 
     WvDriverStateHandle = NULL;
 
@@ -382,6 +384,7 @@ static VOID STDCALL WvUnload(IN PDRIVER_OBJECT DriverObject) {
       PoUnregisterSystemState(WvDriverStateHandle);
     wv_free(WvOsLoadOpts);
     WvDriverStarted = FALSE;
+    WvlDebugModuleUnload();
     DBG("Done\n");
   }