|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
trap.c
Abstract:
WinDbg Extension Api
Revision History:
--*/
#include "precomp.h"
#include "i386.h"
#include "ia64.h"
#pragma hdrstop
extern ULONG64 STeip, STebp, STesp; extern ULONG64 ThreadLastDump;
DECLARE_API( callback )
/*++
Routine Description:
Arguments:
args -
Return Value:
None
--*/
{ ULONG64 Address; ULONG Flags; ULONG result; ULONG64 Thread; ULONG64 prevCallout ; INT calloutNum ; INT whichCallout ; ULONG64 InitialStack; ULONG64 TrFr; ULONG dwProcessor=0; GetCurrentProcessor(Client, &dwProcessor, NULL);
Address = 0; whichCallout = 0 ; if (GetExpressionEx(args, &Address, &args)) { if (!sscanf(args, "%ld", &whichCallout)) { whichCallout = 0; } }
if (Address == 0) { GetCurrentThreadAddr((USHORT)dwProcessor, &Address); }
if (!DumpThreadEx(dwProcessor, "", Address, 0, Client)) return E_INVALIDARG;
GetFieldValue(Address, "ETHREAD", "Tcb.InitialStack", InitialStack); /*
* now try and grab the contents of the stack */ if (GetFieldValue(InitialStack, "KCALLOUT_FRAME", "TrFr", TrFr)) { dprintf("%08p: Unable to get callout frame\n", InitialStack); return E_INVALIDARG; }
if (TargetMachine == IMAGE_FILE_MACHINE_I386) { /*
* Save eip, esp, ebp for quick backtrace from this callback in case * they gave us a bogus callout frame. */ GetFieldValue(InitialStack, "KCALLOUT_FRAME", "Ret", STeip); STesp = (ULONG) InitialStack ; GetFieldValue(InitialStack, "KCALLOUT_FRAME", "Ebp", STebp); }
/*
* Print the callout chain */ calloutNum = 0 ; prevCallout = InitialStack ; if (TargetMachine == IMAGE_FILE_MACHINE_I386) { dprintf("Callout# ebp esp eip trapframe\n") ; } else { dprintf("Callout# esp trapframe\n") ; }
while (prevCallout) {
if (TargetMachine == IMAGE_FILE_MACHINE_I386) { ULONG Ret, Ebp;
GetFieldValue(prevCallout, "KCALLOUT_FRAME", "Ebp", Ebp); GetFieldValue(prevCallout, "KCALLOUT_FRAME", "Ret", Ret);
dprintf(" %3d %08lx %08p %08lx %08lx", calloutNum, Ebp, prevCallout, Ret, TrFr) ; if (calloutNum == whichCallout) { STeip = Ret ; STesp = (ULONG) prevCallout ; STebp = Ebp ; dprintf(" <-- !kb\n") ; } else dprintf("\n") ; } else { dprintf(" %3d %08p %08lx", calloutNum, prevCallout, TrFr) ; }
/*
* advance to the next callout and try to read it */ calloutNum++ ;
GetFieldValue(prevCallout, "KCALLOUT_FRAME", "CbStk", prevCallout); if (GetFieldValue(prevCallout, "KCALLOUT_FRAME", "TrFr", TrFr)) { dprintf("%08p: Unable to get callout frame\n", prevCallout); return E_INVALIDARG; } } dprintf("\n") ;
if (calloutNum <= whichCallout) { dprintf("#(%ld) is out of range. Frame #0 selected.\n", calloutNum) ; }
return S_OK; }
DECLARE_API( kb )
/*++
--*/
{ dprintf("\n"); dprintf(" \"!kb\" is no longer necessary as using \"kb\" after a \".cxr\" or \".trap\"\n"); dprintf(" command will give you the stack for the faulting thread.\n"); dprintf("\n"); dprintf(" Type \"!cxr\" or \"!trap\" for more help on this.\n"); dprintf("\n");
return S_OK; }
DECLARE_API( kv )
/*++
--*/
{ dprintf("\n"); dprintf(" \"!kv\" is no longer necessary as using \"kv\" after a \".cxr\" or \".trap\"\n"); dprintf(" command will give you the stack for the faulting thread.\n"); dprintf("\n"); dprintf(" Type \"!cxr\" or \"!trap\" for more help on this.\n"); dprintf("\n");
return S_OK; }
#define HIGH(x) ((ULONG) ((x>>32) & 0xFFFFFFFF))
#define LOW(x) ((ULONG) (x & 0xFFFFFFFF))
VOID DisplayFullEmRegField( ULONG64 EmRegValue, EM_REG_FIELD EmRegFields[], ULONG Field ) { dprintf( "\n %3.3s : %I64x : %-s", EmRegFields[Field].SubName, (EmRegValue >> EmRegFields[Field].Shift) & ((1 << EmRegFields[Field].Length) - 1), EmRegFields[Field].Name ); return; } // DisplayFullEmRegField()
VOID DisplayFullEmReg( IN ULONG64 Val, IN EM_REG_FIELD EmRegFields[], IN DISPLAY_MODE DisplayMode ) { ULONG i, j;
i = j = 0; if ( DisplayMode >= DISPLAY_MAX ) { while( j < EM_REG_BITS ) { DisplayFullEmRegField( Val, EmRegFields, i ); j += EmRegFields[i].Length; i++; } } else { while( j < EM_REG_BITS ) { if ( !strstr(EmRegFields[i].Name, "reserved" ) && !strstr(EmRegFields[i].Name, "ignored" ) ) { DisplayFullEmRegField( Val, EmRegFields, i ); } j += EmRegFields[i].Length; i++; } } dprintf("\n");
return;
} // DisplayFullEmReg()
#if 0
//
// ISR codes for General Exceptions: ISR{7:4}
//
#define ISR_ILLEGAL_OP 0 // Illegal operation fault
#define ISR_PRIV_OP 1 // Privileged operation fault
#define ISR_PRIV_REG 2 // Privileged register fault
#define ISR_RESVD_REG 3 // Reserved register/field fault
#define ISR_ILLEGAL_ISA 4 // Disabled instruction set transition fault
#define ISR_ILLEGAL_HAZARD 8 // Illegal hazard fault
//
// ISR codes for Nat Consumption Faults: ISR{7:4}
//
#define ISR_NAT_REG 1 // Nat Register Consumption fault
#define ISR_NAT_PAGE 2 // Nat Page Consumption fault
//
// For Traps ISR{4:0}
//
// FP trap
#define ISR_FP_TRAP 0
// Lower privilege transfer trap
#define ISR_LP_TRAP 1
// Taken branch trap
#define ISR_TB_TRAP 2
// Single step trap
#define ISR_SS_TRAP 3
// Unimplemented instruction address trap
#define ISR_UI_TRAP 4
ISR Settings for Non-Access Instructions Instruction ISR fields code{3:0} na r w tpa 0 1 0 0 fc 1 1 1 0 probe 2 1 0 or 1 a 0 or 1 a tak 3 1 0 0 lfetch, lfetch.fault 4 1 1 0 probe.fault 5 1 0 or 1 a 0 or 1 a a. Sets r or w or both to 1 depending on the probe form.
#endif // 0
EM_REG_FIELD EmIsrFields[] = { { "code", "interruption Code" , 0x10, 0 }, // 0-15
{ "vector", "IA32 exception vector number" , 0x8, 16 }, // 16-23
{ "rv", "reserved0", 0x8, 24 }, // 24-31
{ "x", "eXecute exception", 0x1, 32 }, // 32
{ "w", "Write exception", 0x1, 33 }, // 33
{ "r", "Read exception", 0x1, 34 }, // 34
{ "na", "Non-Access exception", 0x1, 35 }, // 35
{ "sp", "Speculative load exception", 0x1, 36 }, // 36
{ "rs", "Register Stack", 0x1, 37 }, // 37
{ "ir", "Invalid Register frame", 0x1, 38 }, // 38
{ "ni", "Nested Interruption", 0x1, 39 }, // 39
{ "so", "IA32 Supervisor Override", 0x1, 40 }, // 40
{ "ei", "Exception IA64 Instruction", 0x2, 41 }, // 41-42
{ "ed", "Exception Deferral", 0x1, 43 }, // 43
{ "rv", "reserved1", 0x14, 44 } // 44-63
};
VOID DisplayIsrIA64( IN const PCHAR Header, IN EM_ISR EmIsr, IN DISPLAY_MODE DisplayMode ) { dprintf("%s", Header ? Header : "" ); if ( DisplayMode >= DISPLAY_MED ) { DisplayFullEmReg( EM_ISRToULong64(EmIsr), EmIsrFields, DisplayMode ); } else { dprintf( "ed ei so ni ir rs sp na r w x vector code\n\t\t " "%1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %I64x %I64x\n", EmIsr.ed, EmIsr.ei, EmIsr.so, EmIsr.ni, EmIsr.ir, EmIsr.rs, EmIsr.sp, EmIsr.na, EmIsr.r, EmIsr.w, EmIsr.x, EmIsr.vector, EmIsr.code ); }
return;
} // DisplayIsrIA64()
DECLARE_API( isr )
/*++
Routine Description:
Arguments:
args -
Return Value:
None
--*/
{ ULONG64 isrValue; ULONG result; ULONG flags = 0; char *header;
if (!GetExpressionEx(args,&isrValue, &args)) { dprintf("USAGE: !isr 0xValue [display_mode:0,1,2]\n"); dprintf("USAGE: !isr @isr [display_mode:0,1,2]\n"); return E_INVALIDARG; } else { flags = (ULONG) GetExpression(args); } header = (flags > DISPLAY_MIN) ? NULL : "\tisr:\t";
if (TargetMachine != IMAGE_FILE_MACHINE_IA64) { dprintf("!isr not implemented for this architecture.\n"); } else { DisplayIsrIA64( header, ULong64ToEM_ISR(isrValue), (DISPLAY_MODE) flags ); }
return S_OK; } // !isr
|