mirror of https://github.com/lianthony/NT4.0
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.
122 lines
3.2 KiB
122 lines
3.2 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
exsup.c
|
|
|
|
Abstract:
|
|
|
|
x86 specific exception handler interpreter functions for
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Kent Forschmiedt (kentf)
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
VOID
|
|
InterpretExceptionData(
|
|
PLAST_EXCEPTION_LOG LogRecord,
|
|
PVOID *Terminator,
|
|
PVOID *Filter,
|
|
PVOID *Handler
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This will examine the exception handler data from an exception
|
|
log entry, and find the address of the handler. If it is a C or
|
|
C++ handler, it will find the scope table for the frame and
|
|
return the filter and handler values for scope that was active
|
|
at the time the exception was dispatched. The log data are from
|
|
the frame based handler, so we cannot tell what happened within
|
|
the frame, we can only see the entry scope and the final disposition
|
|
from the frame.
|
|
|
|
Arguments:
|
|
|
|
LogRecord - Supplies a record as logged by the exception dispatcher.
|
|
|
|
Terminator - Returns the address of the termination or "finally"
|
|
clause for a C/C++ try/finally construct.
|
|
|
|
Filter - Returns the address of the filter clause from a C/C++ try/except.
|
|
|
|
Handler - Returns the address of the handler. If the frame-based handler
|
|
is the C/C++ handler, this is the address of the except clause. If
|
|
it was not the C/C++ handler, the address of the frame-based handler
|
|
is returned, and Filter will return -1.
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
ULONG HandlerAddress;
|
|
ULONG ScopeIndex;
|
|
UCHAR Buffer[100];
|
|
ULONG ScopeTable;
|
|
PVOID ScopeTableEntry[3];
|
|
ULONG cb;
|
|
|
|
// record 0 points to the next chain entry
|
|
HandlerAddress = LogRecord->HandlerData[1];
|
|
ScopeTable = LogRecord->HandlerData[2];
|
|
ScopeIndex = LogRecord->HandlerData[3];
|
|
|
|
|
|
//
|
|
// if the handler is the c or c++ exception handler,
|
|
// there is a scope table of a known format. Otherwise,
|
|
// this is probably a handler in some assembly code,
|
|
// and we have no idea what the data might be. In that
|
|
// case, just show the handler address and be done with it.
|
|
//
|
|
|
|
// Magic!!
|
|
if (ReadMemory(HandlerAddress-8, Buffer, 8, &cb) && cb == 8) {
|
|
|
|
if ( strncmp(Buffer+4, "XC00", 4) == 0 ) {
|
|
|
|
if ( strncmp(Buffer, "VC10", 4) == 0 ||
|
|
strncmp(Buffer, "VC20", 4) == 0 ) {
|
|
|
|
if (ScopeIndex == 0xffffffff) {
|
|
*Terminator = (PVOID)-1;
|
|
*Filter = (PVOID)-1;
|
|
*Handler = (PVOID)-1;
|
|
return;
|
|
} else if (ReadMemory(ScopeTable + 3*ScopeIndex*sizeof(ULONG),
|
|
ScopeTableEntry,
|
|
3 * sizeof(ULONG),
|
|
&cb) &&
|
|
cb == (3 * sizeof(ULONG))) {
|
|
*Terminator = ScopeTableEntry[0];
|
|
*Filter = ScopeTableEntry[1];
|
|
*Handler = ScopeTableEntry[2];
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*Terminator = (PVOID)-1;
|
|
*Filter = (PVOID)-1;
|
|
*Handler = (PVOID)HandlerAddress;
|
|
|
|
return;
|
|
}
|
|
|