+static VOID
+PrintStackTrace(struct _EXCEPTION_POINTERS *ExceptionInfo)
+{
+ PVOID StartAddr;
+ CHAR szMod[128] = "";
+ PEXCEPTION_RECORD ExceptionRecord = ExceptionInfo->ExceptionRecord;
+ PCONTEXT ContextRecord = ExceptionInfo->ContextRecord;
+
+ /* Print a stack trace. */
+ DbgPrint("Unhandled exception\n");
+ DbgPrint("ExceptionCode: %8x\n", ExceptionRecord->ExceptionCode);
+
+ if ((NTSTATUS)ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
+ ExceptionRecord->NumberParameters == 2)
+ {
+ DbgPrint("Faulting Address: %8x\n", ExceptionRecord->ExceptionInformation[1]);
+ }
+
+ _dump_context (ContextRecord);
+ _module_name_from_addr(ExceptionRecord->ExceptionAddress, &StartAddr, szMod, sizeof(szMod));
+ DbgPrint("Address:\n %8x+%-8x %s\n",
+ (PVOID)StartAddr,
+ (ULONG_PTR)ExceptionRecord->ExceptionAddress - (ULONG_PTR)StartAddr,
+ szMod);
+#ifdef _M_IX86
+ DbgPrint("Frames:\n");
+
+ _SEH2_TRY
+ {
+ UINT i;
+ PULONG Frame = (PULONG)ContextRecord->Ebp;
+
+ for (i = 0; Frame[1] != 0 && Frame[1] != 0xdeadbeef && i < 128; i++)
+ {
+ if (IsBadReadPtr((PVOID)Frame[1], 4))
+ {
+ DbgPrint(" %8x%9s %s\n", Frame[1], "<invalid address>"," ");
+ }
+ else
+ {
+ _module_name_from_addr((const void*)Frame[1], &StartAddr,
+ szMod, sizeof(szMod));
+ DbgPrint(" %8x+%-8x %s\n",
+ (PVOID)StartAddr,
+ (ULONG_PTR)Frame[1] - (ULONG_PTR)StartAddr,
+ szMod);
+ }
+
+ if (IsBadReadPtr((PVOID)Frame[0], sizeof(*Frame) * 2))
+ break;
+
+ Frame = (PULONG)Frame[0];
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DbgPrint("<error dumping stack trace: 0x%x>\n", _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+#endif
+}
+