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.
 
 
 
 
 
 

336 lines
9.4 KiB

//----------------------------------------------------------------------------
//
// Generic failure analysis framework.
//
// Copyright (C) Microsoft Corporation, 2001.
//
//----------------------------------------------------------------------------
#ifndef __ANALYZE_H__
#define __ANALYZE_H__
#define E_FAILURE_FOLLOWUP_INFO_NOT_FOUND 0x80100001
#define E_FAILURE_BAD_STACK 0x80100002
#define E_FAILURE_ZEROED_STACK 0x80100003
#define E_FAILURE_WRONG_SYMBOLS 0x80100004
#define E_FAILURE_CORRUPT_MODULE_LIST 0x80100005
#define MAX_STACK_FRAMES 50
typedef enum FOLLOW_ADDRESS
{
FollowYes,
FollowSkip,
FollowStop
} FOLLOW_ADDRESS;
typedef enum FlpClasses
{
FlpIgnore = 0,
FlpOSInternalRoutine, // followups marked as last_ (ignore routines)
FlpOSRoutine, // nt!* or maybe_ followup
FlpOSFilterDrv, // fsfilter!, scsiport! etc.
FlpUnknownDrv,
FlpSpecific, // bugcheck or other source tells us exactly what
// the failure is.
MaxFlpClass
} FlpClasses;
typedef struct _FOLLOWUP_DESCS
{
ULONG64 InstructionOffset;
CHAR Owner[100];
} FOLLOWUP_DESCS, *PFOLLOWUP_DESCS;
typedef struct _FLR_LOOKUP_TABLE {
DEBUG_FLR_PARAM_TYPE Data;
PSTR String;
} FLR_LOOKUP_TABLE, *PFLR_LOOKUP_TABLE;
extern FLR_LOOKUP_TABLE FlrLookupTable[];
struct ModuleParams
{
ModuleParams(PCSTR ModName)
{
m_Name = ModName;
m_Valid = FALSE;
}
ULONG64 GetBase(void)
{
return Update() == S_OK ? m_Base : 0;
}
ULONG GetSize(void)
{
return Update() == S_OK ? m_Size : 0;
}
BOOL Contains(ULONG64 Address)
{
if (Update() == S_OK)
{
return Address >= m_Base && Address < m_Base + m_Size;
}
return FALSE;
}
private:
HRESULT Update(void);
PCSTR m_Name;
BOOL m_Valid;
ULONG64 m_Base;
ULONG m_Size;
};
LONG
FaExceptionFilter(
struct _EXCEPTION_POINTERS *ExceptionInfo
);
BOOL
FaGetSymbol(
ULONG64 Address,
PCHAR Name,
PULONG64 Disp,
ULONG NameSize
);
BOOL
FaIsFunctionAddr(
ULONG64 IP,
PSTR FuncName
);
BOOL
FaGetFollowupInfo(
IN OPTIONAL ULONG64 Addr,
IN OPTIONAL PSTR SymbolName,
OUT OPTIONAL PCHAR Owner,
ULONG OwnerSize
);
BOOL
FaShowFollowUp(
PCHAR Name
);
ULONG64
FaGetImplicitStackOffset(
void
);
LPSTR
TimeToStr(
ULONG TimeDateStamp,
BOOL DateOnly
);
//----------------------------------------------------------------------------
//
// DebugFailureAnalysis.
//
//----------------------------------------------------------------------------
class DebugFailureAnalysis : public IDebugFailureAnalysis
{
public:
DebugFailureAnalysis(void);
~DebugFailureAnalysis(void);
//
// IDebugFailureAnalysis.
//
STDMETHOD(QueryInterface)(
THIS_
IN REFIID InterfaceId,
OUT PVOID* Interface
);
STDMETHOD_(ULONG, AddRef)(
THIS
);
STDMETHOD_(ULONG, Release)(
THIS
);
STDMETHOD_(ULONG, GetFailureClass)(void);
STDMETHOD_(DEBUG_FAILURE_TYPE, GetFailureType)(void);
STDMETHOD_(ULONG, GetFailureCode)(void);
STDMETHOD_(FA_ENTRY*, Get)(FA_TAG Tag);
STDMETHOD_(FA_ENTRY*, GetNext)(FA_ENTRY* Entry, FA_TAG Tag,
FA_TAG TagMask);
STDMETHOD_(FA_ENTRY*, GetString)(FA_TAG Tag, PSTR Str, ULONG MaxSize);
STDMETHOD_(FA_ENTRY*, GetBuffer)(FA_TAG Tag, PVOID Buf, ULONG Size);
STDMETHOD_(FA_ENTRY*, GetUlong)(FA_TAG Tag, PULONG Value);
STDMETHOD_(FA_ENTRY*, GetUlong64)(FA_TAG Tag, PULONG64 Value);
STDMETHOD_(FA_ENTRY*, NextEntry)(FA_ENTRY* Entry);
//
// DebugFailureAnalysis.
//
virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr) = 0;
virtual PCSTR DescribeAddress(ULONG64 Address) = 0;
virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address) = 0;
virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
ULONG64 Address2,
ULONG64 Address3) = 0;
virtual FlpClasses GetFollowupClass(ULONG64 Address,
PCSTR Module, PCSTR Routine) = 0;
virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
ULONG OwnerSize) = 0;
virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames) = 0;
void SetFailureClass(ULONG Class)
{
m_FailureClass = Class;
}
void SetFailureType(DEBUG_FAILURE_TYPE Type)
{
m_FailureType = Type;
}
void SetFailureCode(ULONG Code)
{
m_FailureCode = Code;
}
ULONG GetProcessingFlags(void)
{
return m_ProcessingFlags;
}
void SetProcessingFlags(ULONG Flags)
{
m_ProcessingFlags = Flags;
}
void Output();
void OutputEntry(FA_ENTRY* Entry);
void OutputEntryParam(DEBUG_FLR_PARAM_TYPE Type);
BOOL AddCorruptModules(void);
void GenerateBucketId(void);
void DbFindBucketInfo(void);
void AnalyzeStack(void);
void FindFollowupOnRawStack(ULONG64 StackBase,
PFOLLOWUP_DESCS PossibleFollowups,
FlpClasses *BestClassFollowUp);
BOOL GetTriageInfoFromStack(PDEBUG_STACK_FRAME Stack,
ULONG Frames,
ULONG64 Instruction,
PFOLLOWUP_DESCS PossibleFollowups,
FlpClasses *BestClassFollowUp);
void SetSymbolNameAndModule(void);
HRESULT CheckModuleSymbols(PSTR ModName, PSTR ShowName);
void ProcessInformation(void);
BOOL ProcessInformationPass(void);
FA_ENTRY* Set(FA_TAG Tag, ULONG Size);
FA_ENTRY* SetString(FA_TAG Tag, PSTR Str);
FA_ENTRY* SetStrings(FA_TAG Tag, ULONG Count, PSTR* Strs);
FA_ENTRY* SetBuffer(FA_TAG Tag, PVOID Buf, ULONG Size);
FA_ENTRY* SetUlong(FA_TAG Tag, ULONG Value)
{
FA_ENTRY* Entry = SetBuffer(Tag, &Value, sizeof(Value));
return Entry;
}
FA_ENTRY* SetUlong64(FA_TAG Tag, ULONG64 Value)
{
FA_ENTRY* Entry = SetBuffer(Tag, &Value, sizeof(Value));
return Entry;
}
FA_ENTRY* SetUlong64s(FA_TAG Tag, ULONG Count, PULONG64 Values)
{
FA_ENTRY* Entry = SetBuffer(Tag, Values, Count * sizeof(*Values));
return Entry;
}
FA_ENTRY* Add(FA_TAG Tag, ULONG Size);
ULONG Delete(FA_TAG Tag, FA_TAG TagMask);
void Empty(void);
BOOL IsEmpty(void)
{
return m_DataUsed == 0;
}
BOOL ValidEntry(FA_ENTRY* Entry)
{
return (PUCHAR)Entry >= m_Data &&
(ULONG)((PUCHAR)Entry - m_Data) < m_DataUsed;
}
protected:
ULONG m_Refs;
ULONG m_FailureClass;
DEBUG_FAILURE_TYPE m_FailureType;
ULONG m_FailureCode;
ULONG m_ProcessingFlags;
PUCHAR m_Data;
ULONG m_DataLen;
ULONG m_DataUsed;
FOLLOWUP_DESCS PossibleFollowups[MaxFlpClass];
FlpClasses BestClassFollowUp;
void PackData(PUCHAR Dst, ULONG Len)
{
PUCHAR Src = Dst + Len;
memmove(Dst, Src, m_DataUsed - (ULONG)(Src - m_Data));
m_DataUsed -= Len;
}
FA_ENTRY* AllocateEntry(ULONG FullSize);
};
class KernelDebugFailureAnalysis : public DebugFailureAnalysis
{
public:
KernelDebugFailureAnalysis(void);
virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr);
virtual PCSTR DescribeAddress(ULONG64 Address);
virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address);
virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
ULONG64 Address2,
ULONG64 Address3);
virtual FlpClasses GetFollowupClass(ULONG64 Address,
PCSTR Module, PCSTR Routine);
virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
ULONG OwnerSize);
virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames);
BOOL AddCorruptingPool(ULONG64 Pool);
ModuleParams m_KernelModule;
};
class UserDebugFailureAnalysis : public DebugFailureAnalysis
{
public:
UserDebugFailureAnalysis(void);
virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr);
virtual PCSTR DescribeAddress(ULONG64 Address);
virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address);
virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
ULONG64 Address2,
ULONG64 Address3);
virtual FlpClasses GetFollowupClass(ULONG64 Address,
PCSTR Module, PCSTR Routine);
virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
ULONG OwnerSize);
virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames)
{
return FALSE;
}
ModuleParams m_NtDllModule;
ModuleParams m_Kernel32Module;
ModuleParams m_Advapi32Module;
};
#endif // #ifndef __ANALYZE_H__