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

  1. //----------------------------------------------------------------------------
  2. //
  3. // Generic failure analysis framework.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef __ANALYZE_H__
  9. #define __ANALYZE_H__
  10. #define E_FAILURE_FOLLOWUP_INFO_NOT_FOUND 0x80100001
  11. #define E_FAILURE_BAD_STACK 0x80100002
  12. #define E_FAILURE_ZEROED_STACK 0x80100003
  13. #define E_FAILURE_WRONG_SYMBOLS 0x80100004
  14. #define E_FAILURE_CORRUPT_MODULE_LIST 0x80100005
  15. #define MAX_STACK_FRAMES 50
  16. typedef enum FOLLOW_ADDRESS
  17. {
  18. FollowYes,
  19. FollowSkip,
  20. FollowStop
  21. } FOLLOW_ADDRESS;
  22. typedef enum FlpClasses
  23. {
  24. FlpIgnore = 0,
  25. FlpOSInternalRoutine, // followups marked as last_ (ignore routines)
  26. FlpOSRoutine, // nt!* or maybe_ followup
  27. FlpOSFilterDrv, // fsfilter!, scsiport! etc.
  28. FlpUnknownDrv,
  29. FlpSpecific, // bugcheck or other source tells us exactly what
  30. // the failure is.
  31. MaxFlpClass
  32. } FlpClasses;
  33. typedef struct _FOLLOWUP_DESCS
  34. {
  35. ULONG64 InstructionOffset;
  36. CHAR Owner[100];
  37. } FOLLOWUP_DESCS, *PFOLLOWUP_DESCS;
  38. typedef struct _FLR_LOOKUP_TABLE {
  39. DEBUG_FLR_PARAM_TYPE Data;
  40. PSTR String;
  41. } FLR_LOOKUP_TABLE, *PFLR_LOOKUP_TABLE;
  42. extern FLR_LOOKUP_TABLE FlrLookupTable[];
  43. struct ModuleParams
  44. {
  45. ModuleParams(PCSTR ModName)
  46. {
  47. m_Name = ModName;
  48. m_Valid = FALSE;
  49. }
  50. ULONG64 GetBase(void)
  51. {
  52. return Update() == S_OK ? m_Base : 0;
  53. }
  54. ULONG GetSize(void)
  55. {
  56. return Update() == S_OK ? m_Size : 0;
  57. }
  58. BOOL Contains(ULONG64 Address)
  59. {
  60. if (Update() == S_OK)
  61. {
  62. return Address >= m_Base && Address < m_Base + m_Size;
  63. }
  64. return FALSE;
  65. }
  66. private:
  67. HRESULT Update(void);
  68. PCSTR m_Name;
  69. BOOL m_Valid;
  70. ULONG64 m_Base;
  71. ULONG m_Size;
  72. };
  73. LONG
  74. FaExceptionFilter(
  75. struct _EXCEPTION_POINTERS *ExceptionInfo
  76. );
  77. BOOL
  78. FaGetSymbol(
  79. ULONG64 Address,
  80. PCHAR Name,
  81. PULONG64 Disp,
  82. ULONG NameSize
  83. );
  84. BOOL
  85. FaIsFunctionAddr(
  86. ULONG64 IP,
  87. PSTR FuncName
  88. );
  89. BOOL
  90. FaGetFollowupInfo(
  91. IN OPTIONAL ULONG64 Addr,
  92. IN OPTIONAL PSTR SymbolName,
  93. OUT OPTIONAL PCHAR Owner,
  94. ULONG OwnerSize
  95. );
  96. BOOL
  97. FaShowFollowUp(
  98. PCHAR Name
  99. );
  100. ULONG64
  101. FaGetImplicitStackOffset(
  102. void
  103. );
  104. LPSTR
  105. TimeToStr(
  106. ULONG TimeDateStamp,
  107. BOOL DateOnly
  108. );
  109. //----------------------------------------------------------------------------
  110. //
  111. // DebugFailureAnalysis.
  112. //
  113. //----------------------------------------------------------------------------
  114. class DebugFailureAnalysis : public IDebugFailureAnalysis
  115. {
  116. public:
  117. DebugFailureAnalysis(void);
  118. ~DebugFailureAnalysis(void);
  119. //
  120. // IDebugFailureAnalysis.
  121. //
  122. STDMETHOD(QueryInterface)(
  123. THIS_
  124. IN REFIID InterfaceId,
  125. OUT PVOID* Interface
  126. );
  127. STDMETHOD_(ULONG, AddRef)(
  128. THIS
  129. );
  130. STDMETHOD_(ULONG, Release)(
  131. THIS
  132. );
  133. STDMETHOD_(ULONG, GetFailureClass)(void);
  134. STDMETHOD_(DEBUG_FAILURE_TYPE, GetFailureType)(void);
  135. STDMETHOD_(ULONG, GetFailureCode)(void);
  136. STDMETHOD_(FA_ENTRY*, Get)(FA_TAG Tag);
  137. STDMETHOD_(FA_ENTRY*, GetNext)(FA_ENTRY* Entry, FA_TAG Tag,
  138. FA_TAG TagMask);
  139. STDMETHOD_(FA_ENTRY*, GetString)(FA_TAG Tag, PSTR Str, ULONG MaxSize);
  140. STDMETHOD_(FA_ENTRY*, GetBuffer)(FA_TAG Tag, PVOID Buf, ULONG Size);
  141. STDMETHOD_(FA_ENTRY*, GetUlong)(FA_TAG Tag, PULONG Value);
  142. STDMETHOD_(FA_ENTRY*, GetUlong64)(FA_TAG Tag, PULONG64 Value);
  143. STDMETHOD_(FA_ENTRY*, NextEntry)(FA_ENTRY* Entry);
  144. //
  145. // DebugFailureAnalysis.
  146. //
  147. virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr) = 0;
  148. virtual PCSTR DescribeAddress(ULONG64 Address) = 0;
  149. virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address) = 0;
  150. virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
  151. ULONG64 Address2,
  152. ULONG64 Address3) = 0;
  153. virtual FlpClasses GetFollowupClass(ULONG64 Address,
  154. PCSTR Module, PCSTR Routine) = 0;
  155. virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
  156. ULONG OwnerSize) = 0;
  157. virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames) = 0;
  158. void SetFailureClass(ULONG Class)
  159. {
  160. m_FailureClass = Class;
  161. }
  162. void SetFailureType(DEBUG_FAILURE_TYPE Type)
  163. {
  164. m_FailureType = Type;
  165. }
  166. void SetFailureCode(ULONG Code)
  167. {
  168. m_FailureCode = Code;
  169. }
  170. ULONG GetProcessingFlags(void)
  171. {
  172. return m_ProcessingFlags;
  173. }
  174. void SetProcessingFlags(ULONG Flags)
  175. {
  176. m_ProcessingFlags = Flags;
  177. }
  178. void Output();
  179. void OutputEntry(FA_ENTRY* Entry);
  180. void OutputEntryParam(DEBUG_FLR_PARAM_TYPE Type);
  181. BOOL AddCorruptModules(void);
  182. void GenerateBucketId(void);
  183. void DbFindBucketInfo(void);
  184. void AnalyzeStack(void);
  185. void FindFollowupOnRawStack(ULONG64 StackBase,
  186. PFOLLOWUP_DESCS PossibleFollowups,
  187. FlpClasses *BestClassFollowUp);
  188. BOOL GetTriageInfoFromStack(PDEBUG_STACK_FRAME Stack,
  189. ULONG Frames,
  190. ULONG64 Instruction,
  191. PFOLLOWUP_DESCS PossibleFollowups,
  192. FlpClasses *BestClassFollowUp);
  193. void SetSymbolNameAndModule(void);
  194. HRESULT CheckModuleSymbols(PSTR ModName, PSTR ShowName);
  195. void ProcessInformation(void);
  196. BOOL ProcessInformationPass(void);
  197. FA_ENTRY* Set(FA_TAG Tag, ULONG Size);
  198. FA_ENTRY* SetString(FA_TAG Tag, PSTR Str);
  199. FA_ENTRY* SetStrings(FA_TAG Tag, ULONG Count, PSTR* Strs);
  200. FA_ENTRY* SetBuffer(FA_TAG Tag, PVOID Buf, ULONG Size);
  201. FA_ENTRY* SetUlong(FA_TAG Tag, ULONG Value)
  202. {
  203. FA_ENTRY* Entry = SetBuffer(Tag, &Value, sizeof(Value));
  204. return Entry;
  205. }
  206. FA_ENTRY* SetUlong64(FA_TAG Tag, ULONG64 Value)
  207. {
  208. FA_ENTRY* Entry = SetBuffer(Tag, &Value, sizeof(Value));
  209. return Entry;
  210. }
  211. FA_ENTRY* SetUlong64s(FA_TAG Tag, ULONG Count, PULONG64 Values)
  212. {
  213. FA_ENTRY* Entry = SetBuffer(Tag, Values, Count * sizeof(*Values));
  214. return Entry;
  215. }
  216. FA_ENTRY* Add(FA_TAG Tag, ULONG Size);
  217. ULONG Delete(FA_TAG Tag, FA_TAG TagMask);
  218. void Empty(void);
  219. BOOL IsEmpty(void)
  220. {
  221. return m_DataUsed == 0;
  222. }
  223. BOOL ValidEntry(FA_ENTRY* Entry)
  224. {
  225. return (PUCHAR)Entry >= m_Data &&
  226. (ULONG)((PUCHAR)Entry - m_Data) < m_DataUsed;
  227. }
  228. protected:
  229. ULONG m_Refs;
  230. ULONG m_FailureClass;
  231. DEBUG_FAILURE_TYPE m_FailureType;
  232. ULONG m_FailureCode;
  233. ULONG m_ProcessingFlags;
  234. PUCHAR m_Data;
  235. ULONG m_DataLen;
  236. ULONG m_DataUsed;
  237. FOLLOWUP_DESCS PossibleFollowups[MaxFlpClass];
  238. FlpClasses BestClassFollowUp;
  239. void PackData(PUCHAR Dst, ULONG Len)
  240. {
  241. PUCHAR Src = Dst + Len;
  242. memmove(Dst, Src, m_DataUsed - (ULONG)(Src - m_Data));
  243. m_DataUsed -= Len;
  244. }
  245. FA_ENTRY* AllocateEntry(ULONG FullSize);
  246. };
  247. class KernelDebugFailureAnalysis : public DebugFailureAnalysis
  248. {
  249. public:
  250. KernelDebugFailureAnalysis(void);
  251. virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr);
  252. virtual PCSTR DescribeAddress(ULONG64 Address);
  253. virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address);
  254. virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
  255. ULONG64 Address2,
  256. ULONG64 Address3);
  257. virtual FlpClasses GetFollowupClass(ULONG64 Address,
  258. PCSTR Module, PCSTR Routine);
  259. virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
  260. ULONG OwnerSize);
  261. virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames);
  262. BOOL AddCorruptingPool(ULONG64 Pool);
  263. ModuleParams m_KernelModule;
  264. };
  265. class UserDebugFailureAnalysis : public DebugFailureAnalysis
  266. {
  267. public:
  268. UserDebugFailureAnalysis(void);
  269. virtual DEBUG_POOL_REGION GetPoolForAddress(ULONG64 Addr);
  270. virtual PCSTR DescribeAddress(ULONG64 Address);
  271. virtual FOLLOW_ADDRESS IsPotentialFollowupAddress(ULONG64 Address);
  272. virtual FOLLOW_ADDRESS IsFollowupContext(ULONG64 Address1,
  273. ULONG64 Address2,
  274. ULONG64 Address3);
  275. virtual FlpClasses GetFollowupClass(ULONG64 Address,
  276. PCSTR Module, PCSTR Routine);
  277. virtual BOOL CheckForCorruptionInHTE(ULONG64 hTableEntry,PCHAR Owner,
  278. ULONG OwnerSize);
  279. virtual BOOL IsManualBreakin(PDEBUG_STACK_FRAME Stk, ULONG Frames)
  280. {
  281. return FALSE;
  282. }
  283. ModuleParams m_NtDllModule;
  284. ModuleParams m_Kernel32Module;
  285. ModuleParams m_Advapi32Module;
  286. };
  287. #endif // #ifndef __ANALYZE_H__