8#error This file can only be compiled under Windows. 
   11#pragma comment(lib, "DbgHelp.lib")
 
   28      if(QueryPerformanceCounter(&li) == FALSE)
 
   36      if(QueryPerformanceFrequency(&li) == FALSE)
 
   42      unsigned long long& work_set_size,
 
   43      unsigned long long& work_set_size_peak,
 
   44      unsigned long long& page_file_usage,
 
   45      unsigned long long& page_file_usage_peak)
 
   47      work_set_size = work_set_size_peak = page_file_usage = page_file_usage_peak = 0ull;
 
   50      PROCESS_MEMORY_COUNTERS pmc;
 
   51      memset(&pmc, 0, 
sizeof(PROCESS_MEMORY_COUNTERS));
 
   54      if(GetProcessMemoryInfo(GetCurrentProcess(), &pmc, 
sizeof(PROCESS_MEMORY_COUNTERS)) != FALSE)
 
   56        work_set_size        = pmc.WorkingSetSize;
 
   57        work_set_size_peak   = pmc.PeakWorkingSetSize;
 
   58        page_file_usage      = pmc.PagefileUsage;
 
   59        page_file_usage_peak = pmc.PeakPagefileUsage;
 
   63    void dump_call_stack(CONTEXT& ctx, FILE* stream)
 
   74      HANDLE prc = GetCurrentProcess();
 
   75      HANDLE thr = GetCurrentThread();
 
   78      IMAGEHLP_LINE64 img_line;
 
   79      img_line.SizeOfStruct = 
sizeof(IMAGEHLP_LINE64);
 
   82      memset(&sim, 0, 
sizeof(SYMBOL_INFO) + 512);
 
   83      sim.si.MaxNameLen = 512;
 
   84      sim.si.SizeOfStruct = 
sizeof(SYMBOL_INFO);
 
   87      SymInitialize(prc, 
nullptr, TRUE);
 
   90      STACKFRAME64 stack_frame;
 
   91      memset(&stack_frame, 0, 
sizeof(stack_frame));
 
   94      int machine_type = IMAGE_FILE_MACHINE_AMD64;
 
   95      stack_frame.AddrPC.Offset = ctx.Rip;
 
   96      stack_frame.AddrFrame.Offset = ctx.Rbp;
 
   97      stack_frame.AddrStack.Offset = ctx.Rsp;
 
   99      int machine_type = IMAGE_FILE_MACHINE_I386;
 
  100      stack_frame.AddrPC.Offset = ctx.Eip;
 
  101      stack_frame.AddrFrame.Offset = ctx.Ebp;
 
  102      stack_frame.AddrStack.Offset = ctx.Esp;
 
  104      stack_frame.AddrPC.Mode = AddrModeFlat;
 
  105      stack_frame.AddrFrame.Mode = AddrModeFlat;
 
  106      stack_frame.AddrStack.Mode = AddrModeFlat;
 
  112      fprintf(stream, 
"\nCall-Stack Back-Trace:\n");
 
  113      fprintf(stream,   
"----------------------\n");
 
  116      while (StackWalk64(machine_type, prc, thr, &stack_frame, &ctx, 
nullptr,
 
  117                         &SymFunctionTableAccess64, &SymGetModuleBase64, 
nullptr) != FALSE)
 
  120        addr = stack_frame.AddrPC.Offset;
 
  123        fprintf(stream, 
"0x%0*I64X", 2*
int(
sizeof(
void*)), addr);
 
  126        if(SymFromAddr(prc, addr, 0, &sim.si) != FALSE)
 
  129          fprintf(stream, 
": '%s'", sim.si.Name);
 
  134          fprintf(stream, 
": ???");
 
  138        if(SymGetLineFromAddr64(prc, addr, &line_dsp, &img_line) != FALSE)
 
  141          fprintf(stream, 
" ['%s' @ %i]", img_line.FileName, img_line.LineNumber);
 
  145        fprintf(stream, 
"\n");
 
  156      RtlCaptureContext(&ctx);
 
  159      dump_call_stack(ctx2, stderr);
 
  162    LONG WINAPI FeatWinExceptionFilter(LPEXCEPTION_POINTERS p)
 
  165      fprintf(stderr, 
"\n>>>>> FATAL ERROR <<<<<\n\n");
 
  166      fprintf(stderr, 
"Exception at 0x%0*I64X: ", 2*
int(
sizeof(
void*)), (DWORD64)p->ExceptionRecord->ExceptionAddress);
 
  169      switch(p->ExceptionRecord->ExceptionCode)
 
  172      case EXCEPTION_ACCESS_VIOLATION:
 
  174        fprintf(stderr, 
"Access Violation when ");
 
  175        if(p->ExceptionRecord->ExceptionInformation[0] == 0)
 
  176          fprintf(stderr, 
"reading from");
 
  178          fprintf(stderr, 
"writing to");
 
  179        fprintf(stderr, 
" 0x%0*I64X\n", 2*
int(
sizeof(
void*)), (DWORD64)p->ExceptionRecord->ExceptionInformation[1]);
 
  181      case EXCEPTION_ILLEGAL_INSTRUCTION:
 
  182        fprintf(stderr, 
"Illegal Instruction\n");
 
  184      case EXCEPTION_IN_PAGE_ERROR:
 
  185        fprintf(stderr, 
"Page Error\n");
 
  187      case EXCEPTION_STACK_OVERFLOW:
 
  188        fprintf(stderr, 
"Stack Overflow\n");
 
  192        fprintf(stderr, 
"Error 0x%08X\n", p->ExceptionRecord->ExceptionCode);
 
  197      CONTEXT ctx = *p->ContextRecord;
 
  198      dump_call_stack(ctx, stderr);
 
  201      fprintf(stderr, 
"\n>>>>> TERMINATING <<<<<\n");
 
  205      return EXCEPTION_EXECUTE_HANDLER;
 
  211      SetUnhandledExceptionFilter(FeatWinExceptionFilter);
 
  217      SetErrorMode(GetErrorMode() | SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
 
  219      _set_abort_behavior(0, _WRITE_ABORT_MSG);
 
  224      return GetCurrentProcessId();
 
void install_seh_filter()
Installs custom Windows Structured-Exception-Handler filter.
void dump_call_stack_to_stderr()
Dumps the call-stack to stderr.
void query_memory_usage(unsigned long long &work_set_size, unsigned long long &work_set_size_peak, unsigned long long &page_file_usage, unsigned long long &page_file_usage_peak)
Queries memory usage information.
long long query_performance_frequency()
Wraps around the QueryPerformanceCounter function.
void disable_error_prompts()
Disables Windows error dialog boxes.
unsigned long get_current_process_id()
Returns the Windows process ID for the current process.
long long query_performance_counter()
Wraps around the QueryPerformanceCounter function.