#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, KiInitializeBugCheck)
PVOID
NTAPI
-KiPcToFileHeader(IN PVOID Eip,
+KiPcToFileHeader(IN PVOID Pc,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
IN BOOLEAN DriversOnly,
OUT PBOOLEAN InKernel)
{
ULONG i = 0;
- PVOID ImageBase, EipBase = NULL;
+ PVOID ImageBase, PcBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
ImageBase = Entry->DllBase;
/* Check if this is the right one */
- if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
- ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+ if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+ ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
{
/* Return this entry */
*LdrEntry = Entry;
- EipBase = ImageBase;
+ PcBase = ImageBase;
/* Check if this was a kernel or HAL entry */
if (i <= 2) *InKernel = TRUE;
}
/* Return the base address */
- return EipBase;
+ return PcBase;
}
BOOLEAN
PVOID
NTAPI
-KiRosPcToUserFileHeader(IN PVOID Eip,
+KiRosPcToUserFileHeader(IN PVOID Pc,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
{
- PVOID ImageBase, EipBase = NULL;
+ PVOID ImageBase, PcBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
ImageBase = Entry->DllBase;
/* Check if this is the right one */
- if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
- ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+ if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+ ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
{
/* Return this entry */
*LdrEntry = Entry;
- EipBase = ImageBase;
+ PcBase = ImageBase;
break;
}
}
}
/* Return the base address */
- return EipBase;
+ return PcBase;
}
USHORT
}
VOID
-NTAPI
-KeRosDumpStackFrames(IN PULONG Frame OPTIONAL,
- IN ULONG FrameCount OPTIONAL)
+FASTCALL
+KeRosDumpStackFrameArray(IN PULONG_PTR Frames,
+ IN ULONG FrameCount)
{
- ULONG Frames[32];
- ULONG i, Addr;
+ ULONG i;
+ ULONG_PTR Addr;
BOOLEAN InSystem;
- PLDR_DATA_TABLE_ENTRY LdrEntry;
-
- /* If the caller didn't ask, assume 32 frames */
- if (!FrameCount || FrameCount > 32) FrameCount = 32;
+ PVOID p;
- /* Get the current frames */
- FrameCount = RtlCaptureStackBackTrace(2, FrameCount, (PVOID*)Frames, NULL);
+ /* GCC complaints that it may be used uninitialized */
+ PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
- /* Now loop them (skip the two. One for the dumper, one for the caller) */
+ /* Loop them */
for (i = 0; i < FrameCount; i++)
{
/* Get the EIP */
Addr = Frames[i];
-
- /* If we had a custom frame, make sure we've reached it first */
- if ((Frame) && (Frame[1] == Addr))
- {
- Frame = NULL;
- }
- else if (Frame)
+ if (!Addr)
{
- /* Skip this entry */
- continue;
+ break;
}
/* Get the base for this file */
- if (KiPcToFileHeader((PVOID)Addr, &LdrEntry, FALSE, &InSystem))
+ if (Addr > (ULONG_PTR)MmHighestUserAddress)
{
- /* Print out the module name */
- Addr -= (ULONG_PTR)LdrEntry->DllBase;
- DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr);
+ /* We are in kernel */
+ p = KiPcToFileHeader((PVOID)Addr, &LdrEntry, FALSE, &InSystem);
}
- else if (Addr)
+ else
{
- /* Print only the address */
- DbgPrint("<%x>", Addr);
+ /* We are in user land */
+ p = KiRosPcToUserFileHeader((PVOID)Addr, &LdrEntry);
}
-
- /* Go to the next frame */
- DbgPrint("\n");
- }
-
- /* Get the current frames */
- FrameCount = KeRosCaptureUserStackBackTrace(-1, 32, (PVOID*)Frames, NULL);
-
- /* Now loop them */
- for (i = 0; i < FrameCount; i++)
- {
- /* Get the EIP */
- Addr = Frames[i];
-
- /* Get the base for this file */
- if (KiRosPcToUserFileHeader((PVOID)Addr, &LdrEntry))
+ if (p)
{
- /* Print out the module name */
#ifdef KDBG
if (!KdbSymPrintAddress((PVOID)Addr))
#endif
{
- /* Fall back to usual printing */
+ /* Print out the module name */
Addr -= (ULONG_PTR)LdrEntry->DllBase;
- DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr);
+ DbgPrint("<%wZ: %p>", &LdrEntry->FullDllName, (PVOID)Addr);
}
}
- else if (Addr)
+ else
{
/* Print only the address */
- DbgPrint("<%x>", Addr);
+ DbgPrint("<%p>", (PVOID)Addr);
}
/* Go to the next frame */
DbgPrint("\n");
}
+}
+
+VOID
+NTAPI
+KeRosDumpStackFrames(IN PULONG_PTR Frame OPTIONAL,
+ IN ULONG FrameCount OPTIONAL)
+{
+ ULONG_PTR Frames[32];
+ ULONG RealFrameCount;
+
+ /* If the caller didn't ask, assume 32 frames */
+ if (!FrameCount || FrameCount > 32) FrameCount = 32;
+
+ if (Frame)
+ {
+ /* Dump them */
+ KeRosDumpStackFrameArray(Frame, FrameCount);
+ }
+ else
+ {
+ /* Get the current frames (skip the two. One for the dumper, one for the caller) */
+ RealFrameCount = RtlCaptureStackBackTrace(2, FrameCount, (PVOID*)Frames, NULL);
- /* Finish the output */
- DbgPrint("\n");
+ /* Dump them */
+ KeRosDumpStackFrameArray(Frames, RealFrameCount);
+
+ /* Count left for user mode? */
+ if (FrameCount - RealFrameCount > 0)
+ {
+ /* Get the current frames */
+ RealFrameCount = KeRosCaptureUserStackBackTrace(-1, FrameCount - RealFrameCount, (PVOID*)Frames, NULL);
+
+ /* Dump them */
+ KeRosDumpStackFrameArray(Frames, RealFrameCount);
+ }
+ }
}
+
VOID
NTAPI
KeRosDumpTriageForBugZillaReport(VOID)
NTAPI
KiBugCheckDebugBreak(IN ULONG StatusCode)
{
- /* If KDBG isn't connected, freeze the CPU, otherwise, break */
- if (KdDebuggerNotPresent) for (;;) KeArchHaltProcessor();
- DbgBreakPointWithStatus(StatusCode);
+ /*
+ * Wrap this in SEH so we don't crash if
+ * there is no debugger or if it disconnected
+ */
+DoBreak:
+ _SEH2_TRY
+ {
+ /* Breakpoint */
+ DbgBreakPointWithStatus(StatusCode);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* No debugger, halt the CPU */
+ HalHaltSystem();
+ }
+ _SEH2_END;
+
+ /* Break again if this wasn't first try */
+ if (StatusCode != DBG_STATUS_BUGCHECK_FIRST) goto DoBreak;
}
PCHAR
&InSystem);
if (!ImageBase)
{
- /* Driver wasn't found, check for unloaded driver */
- DriverName = NULL; // FIXME: ROS can't
- if (!DriverName) continue;
-
- /* Convert the driver name */
- ImageBase = (PVOID)Parameters[i];
- ConversionRoutine(DriverName, AnsiName, sizeof(AnsiName));
+ /* FIXME: Add code to check for unloaded drivers */
+ DPRINT1("Potentially unloaded driver!\n");
+ continue;
}
else
{
/* Show the technical Data */
sprintf(AnsiName,
- "\r\n\r\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\r\n\r\n",
- KiBugCheckData[0],
+ "\r\n\r\n*** STOP: 0x%p (0x%p,0x%p,0x%p,0x%p)\r\n\r\n",
+ (PVOID)KiBugCheckData[0],
(PVOID)KiBugCheckData[1],
(PVOID)KiBugCheckData[2],
(PVOID)KiBugCheckData[3],
CHAR AnsiName[128];
BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE;
PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
- PVOID Eip = NULL, Memory;
+ PVOID Pc = NULL, Memory;
PVOID DriverBase;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PULONG_PTR HardErrorParameters;
+ KIRQL OldIrql;
#ifdef CONFIG_SMP
LONG i = 0;
#endif
if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
}
- /* Check if we got one now and if we need to get EIP */
+ /* Check if we got one now and if we need to get the Program Counter */
if ((TrapFrame) &&
(BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
{
-#ifdef _M_IX86
- /* Get EIP */
- Eip = (PVOID)TrapFrame->Eip;
-#elif defined(_M_PPC)
- Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
-#endif
+ /* Get the Program Counter */
+ Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
}
break;
* and provide a more detailed analysis. For now, we don't.
*/
- /* Eip is in parameter 4 */
- Eip = (PVOID)BugCheckParameter4;
+ /* Program Counter is in parameter 4 */
+ Pc = (PVOID)BugCheckParameter4;
/* Get the driver base */
- DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+ DriverBase = KiPcToFileHeader(Pc,
+ &LdrEntry,
+ FALSE,
+ &IsSystem);
if (IsSystem)
{
/*
KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
}
- /* Clear EIP so we don't look it up later */
- Eip = NULL;
+ /* Clear Pc so we don't look it up later */
+ Pc = NULL;
break;
/* Hard error */
/* Check if we have a frame now */
if (TrapFrame)
{
-#ifdef _M_IX86
- /* Get EIP */
- Eip = (PVOID)TrapFrame->Eip;
- KiBugCheckData[3] = (ULONG)Eip;
-#elif defined(_M_PPC)
- Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
- KiBugCheckData[3] = (ULONG)Eip;
-#endif
+ /* Get the Program Counter */
+ Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
+ KiBugCheckData[3] = (ULONG_PTR)Pc;
/* Find out if was in the kernel or drivers */
- DriverBase = KiPcToFileHeader(Eip,
+ DriverBase = KiPcToFileHeader(Pc,
&LdrEntry,
FALSE,
&IsSystem);
/* Check if the driver forgot to unlock pages */
case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:
- /* EIP is in parameter 1 */
- Eip = (PVOID)BugCheckParameter1;
+ /* Program Counter is in parameter 1 */
+ Pc = (PVOID)BugCheckParameter1;
break;
/* Check if the driver consumed too many PTEs */
}
else
{
- /* Do we have an EIP? */
- if (Eip)
+ /* Do we have a Program Counter? */
+ if (Pc)
{
/* Dump image name */
KiDumpParameterImages(AnsiName,
- (PULONG_PTR)&Eip,
+ (PULONG_PTR)&Pc,
1,
KeBugCheckUnicodeToAnsi);
}
/* Check if we need to save the context for KD */
#ifdef _WINKD_
- if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG)&Context;
+ if (!KdPitchDebugger) KdDebuggerDataBlock.SavedContext = (ULONG_PTR)&Context;
#endif
/* Check if a debugger is connected */
/* Raise IRQL to HIGH_LEVEL */
_disable();
- KfRaiseIrql(HIGH_LEVEL);
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Avoid recursion */
if (!InterlockedDecrement((PLONG)&KeBugCheckCount))
if (i != (LONG)KeGetCurrentProcessorNumber())
{
/* Send the IPI and give them one second to catch up */
- KiIpiSendRequest(1 << i, IPI_FREEZE);
+ KiIpiSend(1 << i, IPI_FREEZE);
KeStallExecutionProcessor(1000000);
}
}
#endif
/* Display the BSOD */
- KfLowerIrql(APC_LEVEL); // This is a nastier hack than any ever before
KiDisplayBlueScreen(MessageId,
IsHardError,
HardErrCaption,
HardErrMessage,
AnsiName);
- KfRaiseIrql(HIGH_LEVEL);
/* Check if the debugger is disabled but we can enable it */
if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
/* FIXME: Support Triage Dump */
- /* Write the crash dump */
- MmDumpToPagingFile(KiBugCheckData[4],
- KiBugCheckData[0],
- KiBugCheckData[1],
- KiBugCheckData[2],
- KiBugCheckData[3],
- TrapFrame);
+ /* FIXME: Write the crash dump */
}
else
{
}
else if (KeBugCheckOwnerRecursionCount > 2)
{
- /* Halt the CPU */
- for (;;) KeArchHaltProcessor();
+ /* Halt execution */
+ while (TRUE);
}
}
if (Reboot)
{
/* Unload symbols */
- DbgUnLoadImageSymbols(NULL, NtCurrentProcess(), 0);
+ DbgUnLoadImageSymbols(NULL, (PVOID)MAXULONG_PTR, 0);
HalReturnToFirmware(HalRebootRoutine);
}
/* Attempt to break in the debugger (otherwise halt CPU) */
KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
+
+ /* Shouldn't get here */
+ while (TRUE);
}
/* PUBLIC FUNCTIONS **********************************************************/
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+KeInitializeCrashDumpHeader(IN ULONG Type,
+ IN ULONG Flags,
+ OUT PVOID Buffer,
+ IN ULONG BufferSize,
+ OUT ULONG BufferNeeded OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return STATUS_UNSUCCESSFUL;
+}
+
/*
* @implemented
*/
return Status;
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+KeDeregisterNmiCallback(PVOID Handle)
+{
+ UNIMPLEMENTED;
+ return STATUS_UNSUCCESSFUL;
+}
+
/*
* @implemented
*/
return Status;
}
+/*
+ * @unimplemented
+ */
+PVOID
+NTAPI
+KeRegisterNmiCallback(IN PNMI_CALLBACK CallbackRoutine,
+ IN PVOID Context)
+{
+ UNIMPLEMENTED;
+ return NULL;
+}
+
/*
* @implemented
*/
}
}
- /* Bugcheck */
+ /* Break in the debugger */
KiBugCheckDebugBreak(DBG_STATUS_FATAL);
}