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

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. exceptn.cxx
  5. Abstract:
  6. Contains exception-handling code for debug version
  7. Contents:
  8. SetExceptionHandler
  9. (WininetExceptionFilter)
  10. (MapX86ProcessorFlags)
  11. Author:
  12. Richard L Firth (rfirth) 18-Feb-1997
  13. Revision History:
  14. 18-Feb-1997 rfirth
  15. Created
  16. --*/
  17. #include <wininetp.h>
  18. #include "rprintf.h"
  19. #if INET_DEBUG
  20. //
  21. // private prototypes
  22. //
  23. PRIVATE
  24. LONG
  25. WininetExceptionFilter(
  26. IN PEXCEPTION_POINTERS pExPtrs
  27. );
  28. #if defined(_X86_)
  29. PRIVATE
  30. LPSTR
  31. MapX86ProcessorFlags(
  32. IN DWORD Flags
  33. );
  34. #endif // defined(_X86_)
  35. //
  36. // functions
  37. //
  38. VOID
  39. SetExceptionHandler(
  40. VOID
  41. )
  42. /*++
  43. Routine Description:
  44. Just sets the unhandled exception filter for this process
  45. Arguments:
  46. None.
  47. Return Value:
  48. None.
  49. --*/
  50. {
  51. SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)WininetExceptionFilter);
  52. }
  53. PRIVATE
  54. LONG
  55. WininetExceptionFilter(
  56. IN PEXCEPTION_POINTERS pExPtrs
  57. )
  58. /*++
  59. Routine Description:
  60. We get to look at unhandled exceptions, and dump them to the debug log
  61. Arguments:
  62. pExPtrs - pointer to exception pointers structure
  63. Return Value:
  64. LONG
  65. --*/
  66. {
  67. //
  68. // don't bother if we are not logging
  69. //
  70. if (InternetDebugControlFlags & DBG_NO_DEBUG) {
  71. return EXCEPTION_CONTINUE_SEARCH;
  72. }
  73. LPSTR text;
  74. LONG disposition = EXCEPTION_EXECUTE_HANDLER;
  75. DWORD eipOffset = 0;
  76. switch (pExPtrs->ExceptionRecord->ExceptionCode) {
  77. case EXCEPTION_ACCESS_VIOLATION:
  78. text = "Access Violation";
  79. break;
  80. case EXCEPTION_DATATYPE_MISALIGNMENT:
  81. text = "Data Misalignment Exception";
  82. break;
  83. case EXCEPTION_BREAKPOINT:
  84. text = "Breakpoint Exception";
  85. disposition = EXCEPTION_CONTINUE_EXECUTION;
  86. eipOffset = 1;
  87. break;
  88. case EXCEPTION_SINGLE_STEP:
  89. text = "Single Step Exception";
  90. break;
  91. case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
  92. text = "Array Bounds Exceeded Exception";
  93. break;
  94. case EXCEPTION_FLT_DENORMAL_OPERAND:
  95. case EXCEPTION_FLT_DIVIDE_BY_ZERO:
  96. case EXCEPTION_FLT_INEXACT_RESULT:
  97. case EXCEPTION_FLT_INVALID_OPERATION:
  98. case EXCEPTION_FLT_OVERFLOW:
  99. case EXCEPTION_FLT_STACK_CHECK:
  100. case EXCEPTION_FLT_UNDERFLOW:
  101. text = "Floating Point Exception";
  102. break;
  103. case EXCEPTION_INT_DIVIDE_BY_ZERO:
  104. text = "Integer Divide-By-Zero Exception";
  105. break;
  106. case EXCEPTION_INT_OVERFLOW:
  107. text = "Integer Overflow Exception";
  108. break;
  109. case EXCEPTION_PRIV_INSTRUCTION:
  110. text = "Privileged Instruction Exception";
  111. break;
  112. case EXCEPTION_IN_PAGE_ERROR:
  113. text = "In-Page Error";
  114. break;
  115. case EXCEPTION_ILLEGAL_INSTRUCTION:
  116. text = "Illegal Instruction";
  117. break;
  118. case EXCEPTION_NONCONTINUABLE_EXCEPTION:
  119. text = "Non-Continuable Exception";
  120. break;
  121. case EXCEPTION_STACK_OVERFLOW:
  122. text = "Stack Overflow";
  123. break;
  124. case EXCEPTION_INVALID_DISPOSITION:
  125. text = "Invalid Disposition Exception";
  126. break;
  127. case EXCEPTION_GUARD_PAGE:
  128. text = "Guard Page Exception";
  129. break;
  130. case EXCEPTION_INVALID_HANDLE:
  131. text = "Invalid Handle Exception";
  132. break;
  133. case CONTROL_C_EXIT:
  134. text = "Control-C Exception";
  135. break;
  136. default:
  137. text = "Unknown Exception";
  138. break;
  139. }
  140. InitSymLib();
  141. DWORD dwCodeOffset;
  142. // BUGBUG: Not 64b compatible
  143. LPSTR lpszDebugSymbol = GetDebugSymbol(PtrToUlong(pExPtrs->ExceptionRecord->ExceptionAddress),
  144. &dwCodeOffset
  145. );
  146. char buffer[512];
  147. int offset;
  148. BOOL needCrLf = FALSE;
  149. offset = rsprintf(buffer,
  150. "\n"
  151. "********************************************************************************\n"
  152. "Thread %#x\n"
  153. "%s at %#08x",
  154. GetCurrentThreadId(),
  155. text,
  156. pExPtrs->ExceptionRecord->ExceptionAddress
  157. );
  158. if (dwCodeOffset != (DWORD_PTR)pExPtrs->ExceptionRecord->ExceptionAddress) {
  159. offset += rsprintf(&buffer[offset],
  160. " (%s+%#x)\n",
  161. lpszDebugSymbol,
  162. dwCodeOffset
  163. );
  164. } else {
  165. buffer[offset++] = ' ';
  166. needCrLf = TRUE;
  167. }
  168. if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
  169. rsprintf(&buffer[offset],
  170. "%sing %#08x\n",
  171. pExPtrs->ExceptionRecord->ExceptionInformation[0]
  172. ? "writ"
  173. : "read",
  174. pExPtrs->ExceptionRecord->ExceptionInformation[1]
  175. );
  176. } else if (needCrLf) {
  177. buffer[offset++] = '\r';
  178. buffer[offset++] = '\n';
  179. buffer[offset] = '\0';
  180. }
  181. InternetDebugOut(buffer, FALSE);
  182. #if defined(_X86_)
  183. if ((pExPtrs->ContextRecord->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL) {
  184. rsprintf(buffer,
  185. "\n"
  186. "Processor Context:\n"
  187. "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
  188. "eip=%08x esp=%08x ebp=%08x iopl=%d %s\n"
  189. "cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x efl=%08x\n",
  190. pExPtrs->ContextRecord->Eax,
  191. pExPtrs->ContextRecord->Ebx,
  192. pExPtrs->ContextRecord->Ecx,
  193. pExPtrs->ContextRecord->Edx,
  194. pExPtrs->ContextRecord->Esi,
  195. pExPtrs->ContextRecord->Edi,
  196. pExPtrs->ContextRecord->Eip,
  197. pExPtrs->ContextRecord->Esp,
  198. pExPtrs->ContextRecord->Ebp,
  199. ((pExPtrs->ContextRecord->EFlags & 0x00003000) >> 12),
  200. MapX86ProcessorFlags(pExPtrs->ContextRecord->EFlags),
  201. pExPtrs->ContextRecord->SegCs,
  202. pExPtrs->ContextRecord->SegSs,
  203. pExPtrs->ContextRecord->SegDs,
  204. pExPtrs->ContextRecord->SegEs,
  205. pExPtrs->ContextRecord->SegFs,
  206. pExPtrs->ContextRecord->SegGs,
  207. pExPtrs->ContextRecord->EFlags
  208. );
  209. InternetDebugOut(buffer, FALSE);
  210. }
  211. //
  212. // dump out the stack, debug style
  213. //
  214. LPBYTE Address = (LPBYTE)pExPtrs->ContextRecord->Esp;
  215. rsprintf(buffer,
  216. "\n"
  217. "256 bytes of process stack at %04x:%08x:\n\n",
  218. pExPtrs->ContextRecord->SegSs,
  219. Address
  220. );
  221. InternetDebugOut(buffer, FALSE);
  222. for (DWORD Size = 256; Size; ) {
  223. DWORD nDumped = InternetDebugDumpFormat(Address, 16, sizeof(DWORD), buffer);
  224. InternetDebugOut(buffer, FALSE);
  225. Size -= nDumped;
  226. Address += nDumped;
  227. }
  228. //
  229. // dump call stack
  230. //
  231. LPVOID backtrace[16];
  232. memset(&backtrace, 0, sizeof(backtrace));
  233. x86SleazeCallStack((LPVOID *)backtrace,
  234. ARRAY_ELEMENTS(backtrace),
  235. (LPVOID *)pExPtrs->ContextRecord->Ebp
  236. );
  237. BOOL ok = FALSE;
  238. for (int i = 0; i < ARRAY_ELEMENTS(backtrace); ++i) {
  239. if (backtrace[i] != NULL) {
  240. ok = TRUE;
  241. break;
  242. }
  243. }
  244. if (ok) {
  245. rsprintf(buffer,
  246. "\n"
  247. "Stack back-trace:\n\n"
  248. );
  249. InternetDebugOut(buffer, FALSE);
  250. for (int i = 0; i < ARRAY_ELEMENTS(backtrace); ++i) {
  251. if (backtrace[i] == NULL) {
  252. break;
  253. }
  254. lpszDebugSymbol = GetDebugSymbol((DWORD)backtrace[i], &dwCodeOffset);
  255. rsprintf(buffer,
  256. "%08x %s+%#x\n",
  257. backtrace[i],
  258. lpszDebugSymbol,
  259. dwCodeOffset
  260. );
  261. InternetDebugOut(buffer, FALSE);
  262. }
  263. }
  264. #endif // defined(_X86_)
  265. InternetDebugOut("\r\n********************************************************************************\r\n\r\n", FALSE);
  266. InternetFlushDebugFile();
  267. #if defined(_X86_)
  268. if (disposition == EXCEPTION_CONTINUE_EXECUTION) {
  269. pExPtrs->ContextRecord->Eip += eipOffset;
  270. }
  271. #endif // defined(_X86_)
  272. return disposition;
  273. }
  274. #if defined(_X86_)
  275. PRIVATE
  276. LPSTR
  277. MapX86ProcessorFlags(
  278. IN DWORD Flags
  279. )
  280. {
  281. //
  282. // BUGBUG - not re-entrant
  283. //
  284. static char buf[32 * 3 + 1];
  285. rsprintf(buf,
  286. "%s %s %s %s %s %s %s %s",
  287. (Flags & 0x00000800) ? "ov" : "nv", // Overflow: Overflow or No-overflow
  288. (Flags & 0x00000400) ? "dn" : "up", // Direction: Up or Down
  289. (Flags & 0x00000200) ? "ei" : "di", // Interrupts: Enabled or Disabled
  290. (Flags & 0x00000080) ? "ng" : "pl", // Sign: Negative or Positive
  291. (Flags & 0x00000040) ? "zr" : "nz", // Zero: Zero or Not-zero
  292. (Flags & 0x00000010) ? "ac" : "na", // Aux-Carry: Aux-carry or No-aux-carry
  293. (Flags & 0x00000004) ? "pe" : "po", // Parity: Parity-even or Parity-odd
  294. (Flags & 0x00000001) ? "cy" : "nc" // Carry: Carry or No-carry
  295. );
  296. return buf;
  297. }
  298. #endif // defined(_X86_)
  299. #endif // INET_DEBUG