Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

393 lines
9.7 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
exceptn.cxx
Abstract:
Contains exception-handling code for debug version
Contents:
SetExceptionHandler
(WininetExceptionFilter)
(MapX86ProcessorFlags)
Author:
Richard L Firth (rfirth) 18-Feb-1997
Revision History:
18-Feb-1997 rfirth
Created
--*/
#include <wininetp.h>
#include "rprintf.h"
#if INET_DEBUG
//
// private prototypes
//
PRIVATE
LONG
WininetExceptionFilter(
IN PEXCEPTION_POINTERS pExPtrs
);
#if defined(_X86_)
PRIVATE
LPSTR
MapX86ProcessorFlags(
IN DWORD Flags
);
#endif // defined(_X86_)
//
// functions
//
VOID
SetExceptionHandler(
VOID
)
/*++
Routine Description:
Just sets the unhandled exception filter for this process
Arguments:
None.
Return Value:
None.
--*/
{
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)WininetExceptionFilter);
}
PRIVATE
LONG
WininetExceptionFilter(
IN PEXCEPTION_POINTERS pExPtrs
)
/*++
Routine Description:
We get to look at unhandled exceptions, and dump them to the debug log
Arguments:
pExPtrs - pointer to exception pointers structure
Return Value:
LONG
--*/
{
//
// don't bother if we are not logging
//
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
return EXCEPTION_CONTINUE_SEARCH;
}
LPSTR text;
LONG disposition = EXCEPTION_EXECUTE_HANDLER;
DWORD eipOffset = 0;
switch (pExPtrs->ExceptionRecord->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
text = "Access Violation";
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
text = "Data Misalignment Exception";
break;
case EXCEPTION_BREAKPOINT:
text = "Breakpoint Exception";
disposition = EXCEPTION_CONTINUE_EXECUTION;
eipOffset = 1;
break;
case EXCEPTION_SINGLE_STEP:
text = "Single Step Exception";
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
text = "Array Bounds Exceeded Exception";
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
text = "Floating Point Exception";
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
text = "Integer Divide-By-Zero Exception";
break;
case EXCEPTION_INT_OVERFLOW:
text = "Integer Overflow Exception";
break;
case EXCEPTION_PRIV_INSTRUCTION:
text = "Privileged Instruction Exception";
break;
case EXCEPTION_IN_PAGE_ERROR:
text = "In-Page Error";
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
text = "Illegal Instruction";
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
text = "Non-Continuable Exception";
break;
case EXCEPTION_STACK_OVERFLOW:
text = "Stack Overflow";
break;
case EXCEPTION_INVALID_DISPOSITION:
text = "Invalid Disposition Exception";
break;
case EXCEPTION_GUARD_PAGE:
text = "Guard Page Exception";
break;
case EXCEPTION_INVALID_HANDLE:
text = "Invalid Handle Exception";
break;
case CONTROL_C_EXIT:
text = "Control-C Exception";
break;
default:
text = "Unknown Exception";
break;
}
InitSymLib();
DWORD dwCodeOffset;
// BUGBUG: Not 64b compatible
LPSTR lpszDebugSymbol = GetDebugSymbol(PtrToUlong(pExPtrs->ExceptionRecord->ExceptionAddress),
&dwCodeOffset
);
char buffer[512];
int offset;
BOOL needCrLf = FALSE;
offset = rsprintf(buffer,
"\n"
"********************************************************************************\n"
"Thread %#x\n"
"%s at %#08x",
GetCurrentThreadId(),
text,
pExPtrs->ExceptionRecord->ExceptionAddress
);
if (dwCodeOffset != (DWORD_PTR)pExPtrs->ExceptionRecord->ExceptionAddress) {
offset += rsprintf(&buffer[offset],
" (%s+%#x)\n",
lpszDebugSymbol,
dwCodeOffset
);
} else {
buffer[offset++] = ' ';
needCrLf = TRUE;
}
if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
rsprintf(&buffer[offset],
"%sing %#08x\n",
pExPtrs->ExceptionRecord->ExceptionInformation[0]
? "writ"
: "read",
pExPtrs->ExceptionRecord->ExceptionInformation[1]
);
} else if (needCrLf) {
buffer[offset++] = '\r';
buffer[offset++] = '\n';
buffer[offset] = '\0';
}
InternetDebugOut(buffer, FALSE);
#if defined(_X86_)
if ((pExPtrs->ContextRecord->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL) {
rsprintf(buffer,
"\n"
"Processor Context:\n"
"eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
"eip=%08x esp=%08x ebp=%08x iopl=%d %s\n"
"cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x efl=%08x\n",
pExPtrs->ContextRecord->Eax,
pExPtrs->ContextRecord->Ebx,
pExPtrs->ContextRecord->Ecx,
pExPtrs->ContextRecord->Edx,
pExPtrs->ContextRecord->Esi,
pExPtrs->ContextRecord->Edi,
pExPtrs->ContextRecord->Eip,
pExPtrs->ContextRecord->Esp,
pExPtrs->ContextRecord->Ebp,
((pExPtrs->ContextRecord->EFlags & 0x00003000) >> 12),
MapX86ProcessorFlags(pExPtrs->ContextRecord->EFlags),
pExPtrs->ContextRecord->SegCs,
pExPtrs->ContextRecord->SegSs,
pExPtrs->ContextRecord->SegDs,
pExPtrs->ContextRecord->SegEs,
pExPtrs->ContextRecord->SegFs,
pExPtrs->ContextRecord->SegGs,
pExPtrs->ContextRecord->EFlags
);
InternetDebugOut(buffer, FALSE);
}
//
// dump out the stack, debug style
//
LPBYTE Address = (LPBYTE)pExPtrs->ContextRecord->Esp;
rsprintf(buffer,
"\n"
"256 bytes of process stack at %04x:%08x:\n\n",
pExPtrs->ContextRecord->SegSs,
Address
);
InternetDebugOut(buffer, FALSE);
for (DWORD Size = 256; Size; ) {
DWORD nDumped = InternetDebugDumpFormat(Address, 16, sizeof(DWORD), buffer);
InternetDebugOut(buffer, FALSE);
Size -= nDumped;
Address += nDumped;
}
//
// dump call stack
//
LPVOID backtrace[16];
memset(&backtrace, 0, sizeof(backtrace));
x86SleazeCallStack((LPVOID *)backtrace,
ARRAY_ELEMENTS(backtrace),
(LPVOID *)pExPtrs->ContextRecord->Ebp
);
BOOL ok = FALSE;
for (int i = 0; i < ARRAY_ELEMENTS(backtrace); ++i) {
if (backtrace[i] != NULL) {
ok = TRUE;
break;
}
}
if (ok) {
rsprintf(buffer,
"\n"
"Stack back-trace:\n\n"
);
InternetDebugOut(buffer, FALSE);
for (int i = 0; i < ARRAY_ELEMENTS(backtrace); ++i) {
if (backtrace[i] == NULL) {
break;
}
lpszDebugSymbol = GetDebugSymbol((DWORD)backtrace[i], &dwCodeOffset);
rsprintf(buffer,
"%08x %s+%#x\n",
backtrace[i],
lpszDebugSymbol,
dwCodeOffset
);
InternetDebugOut(buffer, FALSE);
}
}
#endif // defined(_X86_)
InternetDebugOut("\r\n********************************************************************************\r\n\r\n", FALSE);
InternetFlushDebugFile();
#if defined(_X86_)
if (disposition == EXCEPTION_CONTINUE_EXECUTION) {
pExPtrs->ContextRecord->Eip += eipOffset;
}
#endif // defined(_X86_)
return disposition;
}
#if defined(_X86_)
PRIVATE
LPSTR
MapX86ProcessorFlags(
IN DWORD Flags
)
{
//
// BUGBUG - not re-entrant
//
static char buf[32 * 3 + 1];
rsprintf(buf,
"%s %s %s %s %s %s %s %s",
(Flags & 0x00000800) ? "ov" : "nv", // Overflow: Overflow or No-overflow
(Flags & 0x00000400) ? "dn" : "up", // Direction: Up or Down
(Flags & 0x00000200) ? "ei" : "di", // Interrupts: Enabled or Disabled
(Flags & 0x00000080) ? "ng" : "pl", // Sign: Negative or Positive
(Flags & 0x00000040) ? "zr" : "nz", // Zero: Zero or Not-zero
(Flags & 0x00000010) ? "ac" : "na", // Aux-Carry: Aux-carry or No-aux-carry
(Flags & 0x00000004) ? "pe" : "po", // Parity: Parity-even or Parity-odd
(Flags & 0x00000001) ? "cy" : "nc" // Carry: Carry or No-carry
);
return buf;
}
#endif // defined(_X86_)
#endif // INET_DEBUG