From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- .../html/_exception_handler_8cpp_source.html | 546 +++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100644 Doc/doxygen/html/_exception_handler_8cpp_source.html (limited to 'Doc/doxygen/html/_exception_handler_8cpp_source.html') diff --git a/Doc/doxygen/html/_exception_handler_8cpp_source.html b/Doc/doxygen/html/_exception_handler_8cpp_source.html new file mode 100644 index 0000000..3002264 --- /dev/null +++ b/Doc/doxygen/html/_exception_handler_8cpp_source.html @@ -0,0 +1,546 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/ExceptionHandler.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
ExceptionHandler.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 4.5
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2005. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: ExceptionHandler.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 */
+
10 
+
11 
+
12 #include <windows.h>
+
13 #include <imagehlp.h>
+
14 
+
15 extern void Print(const char* fmt, ...);
+
16 
+
17 // +--------------------------------------------------------------------+
+
18 
+ +
20 {
+
21 public:
+ + +
24 
+
25 private:
+
26  static LPTOP_LEVEL_EXCEPTION_FILTER old_filter;
+
27 
+
28  static LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* info);
+
29 
+
30  static void PrintReport(EXCEPTION_POINTERS* info);
+
31 
+
32  // Helper functions
+
33  static const char* GetExceptionString(DWORD dwCode);
+
34  static BOOL GetLogicalAddress(VOID* addr, char* module, int len,
+
35  DWORD& section, DWORD& offset);
+
36 
+
37  static BOOL InitImageHelp();
+
38  static void ImageStackTrace(CONTEXT* context);
+
39  static void IntelStackTrace(CONTEXT* context);
+
40 
+
41 
+
42  // Make typedefs for some IMAGEHLP.DLL functions so that we can use them
+
43  // with GetProcAddress
+
44  typedef BOOL (__stdcall * SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
+
45  typedef BOOL (__stdcall * SYMCLEANUPPROC)(HANDLE);
+
46 
+
47  typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
+
48  typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
+
49  typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
+
50 
+
51  typedef BOOL (__stdcall * STACKWALKPROC)(DWORD,
+
52  HANDLE,
+
53  HANDLE,
+
54  LPSTACKFRAME,
+
55  LPVOID,
+
56  PREAD_PROCESS_MEMORY_ROUTINE,
+
57  PFUNCTION_TABLE_ACCESS_ROUTINE,
+
58  PGET_MODULE_BASE_ROUTINE,
+
59  PTRANSLATE_ADDRESS_ROUTINE);
+
60 
+
61  static SYMINITIALIZEPROC SymInitialize;
+
62  static SYMCLEANUPPROC SymCleanup;
+
63  static STACKWALKPROC StackTrace;
+
64  static SYMFUNCTIONTABLEACCESSPROC SymFunctionTableAccess;
+
65  static SYMGETMODULEBASEPROC SymGetModuleBase;
+
66  static SYMGETSYMFROMADDRPROC SymGetSymFromAddr;
+
67 };
+
68 
+
69 // +--------------------------------------------------------------------+
+
70 
+
71 LPTOP_LEVEL_EXCEPTION_FILTER ExceptionHandler::old_filter = 0;
+
72 
+
73 ExceptionHandler::SYMINITIALIZEPROC ExceptionHandler::SymInitialize = 0;
+
74 ExceptionHandler::SYMCLEANUPPROC ExceptionHandler::SymCleanup = 0;
+
75 ExceptionHandler::STACKWALKPROC ExceptionHandler::StackTrace = 0;
+
76 
+
77 ExceptionHandler::SYMFUNCTIONTABLEACCESSPROC
+
78 ExceptionHandler::SymFunctionTableAccess = 0;
+
79 
+
80 ExceptionHandler::SYMGETMODULEBASEPROC
+
81 ExceptionHandler::SymGetModuleBase = 0;
+
82 
+
83 ExceptionHandler::SYMGETSYMFROMADDRPROC
+
84 ExceptionHandler::SymGetSymFromAddr = 0;
+
85 
+ +
87 
+
88 
+
89 // +--------------------------------------------------------------------+
+
90 
+ +
92 {
+
93  old_filter = SetUnhandledExceptionFilter(ExceptionFilter);
+
94 }
+
95 
+ +
97 {
+
98  SetUnhandledExceptionFilter(old_filter);
+
99 }
+
100 
+
101 // +--------------------------------------------------------------------+
+
102 
+
103 static bool in_filter = false;
+
104 
+
105 LONG WINAPI
+
106 ExceptionHandler::ExceptionFilter(EXCEPTION_POINTERS* info)
+
107 {
+
108  if (in_filter) {
+
109  Print("\n\n*********************************************\n");
+
110  Print("SECOND EXCEPTION CAUGHT: TERMINATING.\n");
+
111  Print("*********************************************\n");
+
112  }
+
113 
+
114  else {
+
115  in_filter = true;
+
116  PrintReport(info);
+
117  in_filter = false;
+
118  }
+
119 
+
120  if (old_filter)
+
121  return old_filter(info);
+
122  else
+
123  return EXCEPTION_CONTINUE_SEARCH;
+
124 }
+
125 
+
126 // +--------------------------------------------------------------------+
+
127 
+
128 void
+
129 ExceptionHandler::PrintReport(EXCEPTION_POINTERS* info)
+
130 {
+
131  EXCEPTION_RECORD* record = info->ExceptionRecord;
+
132  CONTEXT* context = info->ContextRecord;
+
133  DWORD code = record->ExceptionCode;
+
134 
+
135  Print("\n*********************************************\n");
+
136  Print("FATAL EXCEPTION:\n");
+
137 
+
138  Print("\nRegisters:\n");
+
139  Print("EAX: %08x\n", context->Eax);
+
140  Print("EBX: %08x\n", context->Ebx);
+
141  Print("ECX: %08x\n", context->Ecx);
+
142  Print("EDX: %08x\n", context->Edx);
+
143  Print("EDI: %08x\n", context->Edi);
+
144  Print("ESI: %08x\n", context->Esi);
+
145  Print("EBP: %08x\n", context->Ebp);
+
146  Print("\n");
+
147  Print("CS:EIP: %04x:%08x\n", context->SegCs, context->Eip);
+
148  Print("SS:ESP: %04x:%08x\n", context->SegSs, context->Esp);
+
149  Print("DS: %04x\n", context->SegDs);
+
150  Print("ES: %04x\n", context->SegEs);
+
151  Print("FS: %04x\n", context->SegFs);
+
152  Print("GS: %04x\n", context->SegGs);
+
153  Print("Flags: %08x\n", context->EFlags );
+
154  Print("\n");
+
155 
+
156  Print("Exception Code: %08x %s\n",code, GetExceptionString(code));
+
157  Print("Exception Addr: %08x \n", record->ExceptionAddress);
+
158 
+
159  if (code == EXCEPTION_ACCESS_VIOLATION && record->NumberParameters >= 2) {
+
160  if (record->ExceptionInformation[0])
+
161  Print(" Program attempted to WRITE to address 0x%08x\n", record->ExceptionInformation[1]);
+
162  else
+
163  Print(" Program attempted to READ from address 0x%08x\n", record->ExceptionInformation[1]);
+
164  }
+
165 
+
166  if (InitImageHelp()) {
+
167  ImageStackTrace(context);
+
168  SymCleanup(GetCurrentProcess());
+
169  }
+
170  else {
+
171  IntelStackTrace(context);
+
172  }
+
173 
+
174  Print("\n*********************************************\nPROGRAM TERMINATED.\n");
+
175 }
+
176 
+
177 // +--------------------------------------------------------------------+
+
178 
+
179 const char*
+
180 ExceptionHandler::GetExceptionString(DWORD code)
+
181 {
+
182 #define EXCEPTION( x ) case EXCEPTION_##x: return #x;
+
183 
+
184  switch (code) {
+
185  EXCEPTION( ACCESS_VIOLATION )
+
186  EXCEPTION( DATATYPE_MISALIGNMENT )
+
187  EXCEPTION( BREAKPOINT )
+
188  EXCEPTION( SINGLE_STEP )
+
189  EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
+
190  EXCEPTION( FLT_DENORMAL_OPERAND )
+
191  EXCEPTION( FLT_DIVIDE_BY_ZERO )
+
192  EXCEPTION( FLT_INEXACT_RESULT )
+
193  EXCEPTION( FLT_INVALID_OPERATION )
+
194  EXCEPTION( FLT_OVERFLOW )
+
195  EXCEPTION( FLT_STACK_CHECK )
+
196  EXCEPTION( FLT_UNDERFLOW )
+
197  EXCEPTION( INT_DIVIDE_BY_ZERO )
+
198  EXCEPTION( INT_OVERFLOW )
+
199  EXCEPTION( PRIV_INSTRUCTION )
+
200  EXCEPTION( IN_PAGE_ERROR )
+
201  EXCEPTION( ILLEGAL_INSTRUCTION )
+
202  EXCEPTION( NONCONTINUABLE_EXCEPTION )
+
203  EXCEPTION( STACK_OVERFLOW )
+
204  EXCEPTION( INVALID_DISPOSITION )
+
205  EXCEPTION( GUARD_PAGE )
+
206  EXCEPTION( INVALID_HANDLE )
+
207  }
+
208 
+
209  static char buffer[512] = { 0 };
+
210 
+
211  FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
+
212  GetModuleHandle("NTDLL.DLL"),
+
213  code, 0, buffer, sizeof(buffer), 0 );
+
214 
+
215  return buffer;
+
216 }
+
217 
+
218 // +--------------------------------------------------------------------+
+
219 
+
220 BOOL
+
221 ExceptionHandler::GetLogicalAddress(void* addr, char* mod_name, int len, DWORD& section, DWORD& offset)
+
222 {
+
223  MEMORY_BASIC_INFORMATION mbi;
+
224 
+
225  if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
+
226  return FALSE;
+
227 
+
228  DWORD hMod = (DWORD)mbi.AllocationBase;
+
229 
+
230  if (!GetModuleFileName((HMODULE)hMod, mod_name, len))
+
231  return FALSE;
+
232 
+
233  PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) hMod;
+
234  PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
+
235  PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
+
236 
+
237  DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
+
238 
+
239  // Iterate through the section table, looking for the one that encompasses
+
240  // the linear address.
+
241  for (unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++ ) {
+
242  DWORD sectionStart = pSection->VirtualAddress;
+
243  DWORD sectionEnd = sectionStart
+
244  + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
+
245 
+
246  // Is the address in this section???
+
247  if ((rva >= sectionStart) && (rva <= sectionEnd)) {
+
248  // Yes, address is in the section. Calculate section and offset,
+
249  // and store in the "section" & "offset" params, which were
+
250  // passed by reference.
+
251  section = i+1;
+
252  offset = rva - sectionStart;
+
253  return TRUE;
+
254  }
+
255  }
+
256 
+
257  return FALSE; // Should never get here!
+
258 }
+
259 
+
260 // +--------------------------------------------------------------------+
+
261 
+
262 void
+
263 ExceptionHandler::IntelStackTrace(CONTEXT* context)
+
264 {
+
265  Print("\nStack Trace (Intel):\n");
+
266  Print("Address Frame Logical addr Module\n");
+
267 
+
268  DWORD pc = context->Eip;
+
269  DWORD* pFrame;
+
270  DWORD* pPrevFrame;
+
271 
+
272  pFrame = (DWORD*)context->Ebp;
+
273 
+
274  do {
+
275  char mod_name[256] = { 0 };
+
276  DWORD section = 0, offset = 0;
+
277 
+
278  GetLogicalAddress((void*)pc, mod_name, 256, section, offset);
+
279 
+
280  Print("%08X %08X %04X:%08X %s\n",
+
281  pc, pFrame, section, offset, mod_name);
+
282 
+
283  pc = pFrame[1];
+
284  pPrevFrame = pFrame;
+
285  pFrame = (PDWORD)pFrame[0]; // proceed to next higher frame on stack
+
286 
+
287  if ((DWORD)pFrame & 3) // Frame pointer must be aligned on a
+
288  break; // DWORD boundary. Bail if not so.
+
289 
+
290  if (pFrame <= pPrevFrame)
+
291  break;
+
292 
+
293  // Can two DWORDs be read from the supposed frame address?
+
294  if (IsBadWritePtr(pFrame, sizeof(PVOID)*2))
+
295  break;
+
296 
+
297  }
+
298  while ( 1 );
+
299 }
+
300 
+
301 // +--------------------------------------------------------------------+
+
302 
+
303 void ExceptionHandler::ImageStackTrace(CONTEXT* context)
+
304 {
+
305  Print("\nStack Trace (Symbolic):\n");
+
306  Print("Address Frame\n");
+
307 
+
308  // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
+
309  STACKFRAME sf;
+
310  memset(&sf, 0, sizeof(sf));
+
311 
+
312  // Initialize the STACKFRAME structure for the first call. This is only
+
313  // necessary for Intel CPUs, and isn't mentioned in the documentation.
+
314  sf.AddrPC.Offset = context->Eip;
+
315  sf.AddrPC.Mode = AddrModeFlat;
+
316  sf.AddrStack.Offset = context->Esp;
+
317  sf.AddrStack.Mode = AddrModeFlat;
+
318  sf.AddrFrame.Offset = context->Ebp;
+
319  sf.AddrFrame.Mode = AddrModeFlat;
+
320 
+
321  while ( 1 ) {
+
322  if (!StackTrace( IMAGE_FILE_MACHINE_I386,
+
323  GetCurrentProcess(),
+
324  GetCurrentThread(),
+
325  &sf,
+
326  context,
+
327  0,
+
328  SymFunctionTableAccess,
+
329  SymGetModuleBase,
+
330  0))
+
331  break;
+
332 
+
333  if (sf.AddrFrame.Offset == 0) // Basic sanity check to make sure
+
334  break; // the frame is OK. Bail if not.
+
335 
+
336  Print("%08x %08x ", sf.AddrPC.Offset, sf.AddrFrame.Offset);
+
337 
+
338  // IMAGEHLP is wacky, and requires you to pass in a pointer to an
+
339  // IMAGEHLP_SYMBOL structure. The problem is that this structure is
+
340  // variable length. That is, you determine how big the structure is
+
341  // at runtime. This means that you can't use sizeof(struct).
+
342  // So...make a buffer that's big enough, and make a pointer
+
343  // to the buffer. We also need to initialize not one, but TWO
+
344  // members of the structure before it can be used.
+
345 
+
346  BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
+
347  PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
+
348  pSymbol->SizeOfStruct = sizeof(symbolBuffer);
+
349  pSymbol->MaxNameLength = 512;
+
350 
+
351  DWORD symDisplacement = 0; // Displacement of the input address,
+
352  // relative to the start of the symbol
+
353 
+
354  if (SymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset,
+
355  &symDisplacement, pSymbol)) {
+
356  Print("%-40s [%04X]\n", pSymbol->Name, symDisplacement);
+
357  }
+
358  else {
+
359  char mod_name[256] = { 0 };
+
360  DWORD section = 0, offset = 0;
+
361 
+
362  GetLogicalAddress((PVOID)sf.AddrPC.Offset,
+
363  mod_name, 256, section, offset );
+
364 
+
365  Print("%04X:%08X %s\n", section, offset, mod_name);
+
366  }
+
367  }
+
368 }
+
369 
+
370 // +--------------------------------------------------------------------+
+
371 
+
372 BOOL
+
373 ExceptionHandler::InitImageHelp()
+
374 {
+
375  Print("\n");
+
376 
+
377  HMODULE h = LoadLibrary("IMAGEHLP.DLL");
+
378  if (!h) {
+
379  Print("--- could not load IMAGEHLP.DLL (%08x) ---\n", GetLastError());
+
380  return FALSE;
+
381  }
+
382 
+
383  SymInitialize = (SYMINITIALIZEPROC) GetProcAddress(h, "SymInitialize");
+
384  if (!SymInitialize) {
+
385  Print("--- could not find SymInitialize ---\n");
+
386  return FALSE;
+
387  }
+
388 
+
389  SymCleanup = (SYMCLEANUPPROC) GetProcAddress(h, "SymCleanup");
+
390  if (!SymCleanup) {
+
391  Print("--- could not find SymCleanup ---\n");
+
392  return FALSE;
+
393  }
+
394 
+
395  StackTrace = (STACKWALKPROC) GetProcAddress(h, "StackWalk");
+
396  if (!StackTrace) {
+
397  Print("--- could not find StackWalk ---\n");
+
398  return FALSE;
+
399  }
+
400 
+
401  SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC)
+
402  GetProcAddress(h, "SymFunctionTableAccess");
+
403 
+
404  if (!SymFunctionTableAccess) {
+
405  Print("--- could not find SymFunctionTableAccess ---\n");
+
406  return FALSE;
+
407  }
+
408 
+
409  SymGetModuleBase = (SYMGETMODULEBASEPROC) GetProcAddress(h, "SymGetModuleBase");
+
410  if (!SymGetModuleBase) {
+
411  Print("--- could not find SymGetModuleBase ---\n");
+
412  return FALSE;
+
413  }
+
414 
+
415  SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC) GetProcAddress(h, "SymGetSymFromAddr");
+
416  if (!SymGetSymFromAddr) {
+
417  Print("--- could not find SymGetSymFromAddr ---\n");
+
418  return FALSE;
+
419  }
+
420 
+
421  if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) {
+
422  Print("--- could not Initialize IMAGEHLP.DLL (%08x) ---\n", GetLastError());
+
423  return FALSE;
+
424  }
+
425 
+
426  Print("Loaded IMAGEHLP.DLL\n");
+
427  return TRUE;
+
428 }
+
429 
+
+
+ + + + -- cgit v1.1