21 #ifdef USE_WINDOWS_SEH 
   31     const ULONG maxnamelength = 512;
 
   32     struct IMAGEHLP_SYMBOL64_EXT : 
public IMAGEHLP_SYMBOL64 {
 
   33         TCHAR nameExt[maxnamelength]; 
 
   35     typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64);
 
   36     fpStackWalk64 pStackWalk64;
 
   37     typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
 
   38     fpSymGetModuleBase64 pSymGetModuleBase64;
 
   39     typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
 
   40     fpSymGetSymFromAddr64 pSymGetSymFromAddr64;
 
   41     typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
 
   42     fpSymGetLineFromAddr64 pSymGetLineFromAddr64;
 
   43     typedef DWORD (WINAPI *fpUnDecorateSymbolName)(
const TCHAR*, PTSTR, DWORD, DWORD);
 
   44     fpUnDecorateSymbolName pUnDecorateSymbolName;
 
   45     typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
 
   46     fpSymFunctionTableAccess64 pSymFunctionTableAccess64;
 
   47     typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
 
   48     fpSymInitialize pSymInitialize;
 
   54         hLibDbgHelp = ::LoadLibraryW(L
"Dbghelp.dll");
 
   57         pStackWalk64 = (fpStackWalk64) ::GetProcAddress(hLibDbgHelp, 
"StackWalk64");
 
   58         pSymGetModuleBase64 = (fpSymGetModuleBase64) ::GetProcAddress(hLibDbgHelp, 
"SymGetModuleBase64");
 
   59         pSymGetSymFromAddr64 = (fpSymGetSymFromAddr64) ::GetProcAddress(hLibDbgHelp, 
"SymGetSymFromAddr64");
 
   60         pSymGetLineFromAddr64 = (fpSymGetLineFromAddr64)::GetProcAddress(hLibDbgHelp, 
"SymGetLineFromAddr64");
 
   61         pSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)::GetProcAddress(hLibDbgHelp, 
"SymFunctionTableAccess64");
 
   62         pSymInitialize = (fpSymInitialize) ::GetProcAddress(hLibDbgHelp, 
"SymInitialize");
 
   63         pUnDecorateSymbolName = (fpUnDecorateSymbolName)::GetProcAddress(hLibDbgHelp, 
"UnDecorateSymbolName");
 
   68     void printCallstack(FILE* outputFile, PEXCEPTION_POINTERS ex)
 
   72         const HANDLE hProcess   = GetCurrentProcess();
 
   73         const HANDLE hThread    = GetCurrentThread();
 
   79         CONTEXT context = *(ex->ContextRecord);
 
   80         STACKFRAME64 stack= {0};
 
   82         stack.AddrPC.Offset    = context.Eip;
 
   83         stack.AddrPC.Mode      = AddrModeFlat;
 
   84         stack.AddrStack.Offset = context.Esp;
 
   85         stack.AddrStack.Mode   = AddrModeFlat;
 
   86         stack.AddrFrame.Offset = context.Ebp;
 
   87         stack.AddrFrame.Mode   = AddrModeFlat;
 
   89         stack.AddrPC.Offset    = context.Rip;
 
   90         stack.AddrPC.Mode      = AddrModeFlat;
 
   91         stack.AddrStack.Offset = context.Rsp;
 
   92         stack.AddrStack.Mode   = AddrModeFlat;
 
   93         stack.AddrFrame.Offset = context.Rsp;
 
   94         stack.AddrFrame.Mode   = AddrModeFlat;
 
   96         IMAGEHLP_SYMBOL64_EXT symbol;
 
   97         symbol.SizeOfStruct  = 
sizeof(IMAGEHLP_SYMBOL64);
 
   98         symbol.MaxNameLength = maxnamelength;
 
   99         DWORD64 displacement   = 0;
 
  101         for (ULONG frame = 0; ; frame++) {
 
  102             BOOL result = pStackWalk64
 
  105                 IMAGE_FILE_MACHINE_I386,
 
  107                 IMAGE_FILE_MACHINE_AMD64,
 
  114                 pSymFunctionTableAccess64,
 
  120             pSymGetSymFromAddr64(hProcess, (ULONG64)stack.AddrPC.Offset, &displacement, &symbol);
 
  121             TCHAR undname[maxnamelength]= {0};
 
  122             pUnDecorateSymbolName((
const TCHAR*)symbol.Name, (PTSTR)undname, (DWORD)
getArrayLength(undname), UNDNAME_COMPLETE);
 
  125             if (_tcscmp(undname, _T(
"main"))==0)
 
  128                     "%lu. 0x%08I64X in ",
 
  129                     frame, (ULONG64)stack.AddrPC.Offset);
 
  130             fputs((
const char *)undname, outputFile);
 
  131             fputc(
'\n', outputFile);
 
  132             if (0==stack.AddrReturn.Offset || beyond_main>2) 
 
  136         FreeLibrary(hLibDbgHelp);
 
  140     void writeMemoryErrorDetails(FILE* outputFile, PEXCEPTION_POINTERS ex, 
const char* description)
 
  142         fputs(description, outputFile);
 
  143         fprintf(outputFile, 
" (instruction: 0x%p) ", ex->ExceptionRecord->ExceptionAddress);
 
  146         C_ASSERT(
sizeof(
void*) == 
sizeof(ex->ExceptionRecord->ExceptionInformation[1]));
 
  147         switch (ex->ExceptionRecord->ExceptionInformation[0]) {
 
  149             fprintf(outputFile, 
"reading from 0x%p",
 
  150                     reinterpret_cast<void*
>(ex->ExceptionRecord->ExceptionInformation[1]));
 
  153             fprintf(outputFile, 
"writing to 0x%p",
 
  154                     reinterpret_cast<void*
>(ex->ExceptionRecord->ExceptionInformation[1]));
 
  157             fprintf(outputFile, 
"data execution prevention at 0x%p",
 
  158                     reinterpret_cast<void*
>(ex->ExceptionRecord->ExceptionInformation[1]));
 
  168     int filterException(FILE *outputFile, 
int code, PEXCEPTION_POINTERS ex)
 
  170         fputs(
"Internal error: ", outputFile);
 
  171         switch (ex->ExceptionRecord->ExceptionCode) {
 
  172         case EXCEPTION_ACCESS_VIOLATION:
 
  173             writeMemoryErrorDetails(outputFile, ex, 
"Access violation");
 
  175         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
 
  176             fputs(
"Out of array bounds", outputFile);
 
  178         case EXCEPTION_BREAKPOINT:
 
  179             fputs(
"Breakpoint", outputFile);
 
  181         case EXCEPTION_DATATYPE_MISALIGNMENT:
 
  182             fputs(
"Misaligned data", outputFile);
 
  184         case EXCEPTION_FLT_DENORMAL_OPERAND:
 
  185             fputs(
"Denormalized floating-point value", outputFile);
 
  187         case EXCEPTION_FLT_DIVIDE_BY_ZERO:
 
  188             fputs(
"Floating-point divide-by-zero", outputFile);
 
  190         case EXCEPTION_FLT_INEXACT_RESULT:
 
  191             fputs(
"Inexact floating-point value", outputFile);
 
  193         case EXCEPTION_FLT_INVALID_OPERATION:
 
  194             fputs(
"Invalid floating-point operation", outputFile);
 
  196         case EXCEPTION_FLT_OVERFLOW:
 
  197             fputs(
"Floating-point overflow", outputFile);
 
  199         case EXCEPTION_FLT_STACK_CHECK:
 
  200             fputs(
"Floating-point stack overflow", outputFile);
 
  202         case EXCEPTION_FLT_UNDERFLOW:
 
  203             fputs(
"Floating-point underflow", outputFile);
 
  205         case EXCEPTION_GUARD_PAGE:
 
  206             fputs(
"Page-guard access", outputFile);
 
  208         case EXCEPTION_ILLEGAL_INSTRUCTION:
 
  209             fputs(
"Illegal instruction", outputFile);
 
  211         case EXCEPTION_IN_PAGE_ERROR:
 
  212             writeMemoryErrorDetails(outputFile, ex, 
"Invalid page access");
 
  214         case EXCEPTION_INT_DIVIDE_BY_ZERO:
 
  215             fputs(
"Integer divide-by-zero", outputFile);
 
  217         case EXCEPTION_INT_OVERFLOW:
 
  218             fputs(
"Integer overflow", outputFile);
 
  220         case EXCEPTION_INVALID_DISPOSITION:
 
  221             fputs(
"Invalid exception dispatcher", outputFile);
 
  223         case EXCEPTION_INVALID_HANDLE:
 
  224             fputs(
"Invalid handle", outputFile);
 
  226         case EXCEPTION_NONCONTINUABLE_EXCEPTION:
 
  227             fputs(
"Non-continuable exception", outputFile);
 
  229         case EXCEPTION_PRIV_INSTRUCTION:
 
  230             fputs(
"Invalid instruction", outputFile);
 
  232         case EXCEPTION_SINGLE_STEP:
 
  233             fputs(
"Single instruction step", outputFile);
 
  235         case EXCEPTION_STACK_OVERFLOW:
 
  236             fputs(
"Stack overflow", outputFile);
 
  239             fprintf(outputFile, 
"Unknown exception (%d)\n",
 
  243         fputc(
'\n', outputFile);
 
  244         printCallstack(outputFile, ex);
 
  246         return EXCEPTION_EXECUTE_HANDLER;
 
  260         return (&executor->*f)(settings);
 
  261     } __except (filterException(outputFile, GetExceptionCode(), GetExceptionInformation())) {
 
  262         fputs(
"Please report this to the cppcheck developers!\n", outputFile);
 
This class works as an example of how CppCheck can be used in external programs without very little k...
 
static FILE * getExceptionOutput()
 
This is just a container for general settings so that we don't need to pass individual values to func...
 
std::size_t getArrayLength(const T(&)[size])
Simple helper function: