| 
					
				 | 
			
			
				@@ -61,45 +61,7 @@ static unsigned seed(void) { return (unsigned)_getpid(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #pragma comment(lib, "dbghelp.lib") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void print_current_stack() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  typedef USHORT(WINAPI * CaptureStackBackTraceType)( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      __in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (func == NULL) return;  // WOE 29.SEP.2010 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Quote from Microsoft Documentation: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// ## Windows Server 2003 and Windows XP: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// ## The sum of the FramesToSkip and FramesToCapture parameters must be less 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// than 63. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#define MAX_CALLERS 62 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  void* callers_stack[MAX_CALLERS]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unsigned short frames; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SYMBOL_INFOW* symbol; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  HANDLE process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  process = GetCurrentProcess(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SymInitialize(process, NULL, TRUE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  frames = (func)(0, MAX_CALLERS, callers_stack, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  symbol = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      (SYMBOL_INFOW*)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  symbol->MaxNameLen = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const unsigned short MAX_CALLERS_SHOWN = 32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (unsigned int i = 0; i < frames; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fflush(stderr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  free(symbol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static void print_stack_from_context(CONTEXT c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void print_stack_from_context(HANDLE thread, CONTEXT c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   STACKFRAME s;  // in/out stackframe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memset(&s, 0, sizeof(s)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   DWORD imageType; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -135,26 +97,42 @@ static void print_stack_from_context(CONTEXT c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   HANDLE process = GetCurrentProcess(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  HANDLE thread = GetCurrentThread(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SYMBOL_INFOW* symbol = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (SYMBOL_INFOW*)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   symbol->MaxNameLen = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  while (StackWalk(imageType, process, thread, &s, &c, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   SymFunctionTableAccess, SymGetModuleBase, 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BOOL has_symbol = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fwprintf( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        has_symbol ? symbol->Name : L"<<no symbol>>", (DWORD64)symbol->Address); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const unsigned short MAX_CALLERS_SHOWN = 32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (int frame = 0; frame < MAX_CALLERS_SHOWN && StackWalk(imageType, process, thread, &s, &c, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   SymFunctionTableAccess, SymGetModuleBase, 0); frame++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    PWSTR file_name = L"<<no line info>>"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int line_number = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    IMAGEHLP_LINE line; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    line.SizeOfStruct = sizeof(IMAGEHLP_LINE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DWORD displacement = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (SymGetLineFromAddrW(process, (DWORD64)(s.AddrPC.Offset), &displacement, &line)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file_name = line.FileName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        line_number = (int)line.LineNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X (%ls:%d)\n", frame, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             (DWORD64)(s.AddrPC.Offset), symbol->Name, (DWORD64)symbol->Address, file_name, line_number); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fflush(stderr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   free(symbol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void print_current_stack() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CONTEXT context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  RtlCaptureContext(&context); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  print_stack_from_context(GetCurrentThread(), context); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static LONG crash_handler(struct _EXCEPTION_POINTERS* ex_info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   fprintf(stderr, "Exception handler called, dumping information\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bool try_to_print_stack = true; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -168,7 +146,7 @@ static LONG crash_handler(struct _EXCEPTION_POINTERS* ex_info) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     exrec = exrec->ExceptionRecord; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (try_to_print_stack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print_stack_from_context(*ex_info->ContextRecord); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print_stack_from_context(GetCurrentThread(), *ex_info->ContextRecord); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (IsDebuggerPresent()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     __debugbreak(); 
			 |