| 353 | |
| 354 | #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) |
| 355 | void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep) |
| 356 | { |
| 357 | if(!ep) fatal("unknown type"); |
| 358 | EXCEPTION_RECORD *er = ep->ExceptionRecord; |
| 359 | CONTEXT *context = ep->ContextRecord; |
| 360 | string out, t; |
| 361 | formatstring(out)("Win32 Exception: 0x%x [0x%x]\n\n", er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1); |
| 362 | STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0}; |
| 363 | SymInitialize(GetCurrentProcess(), NULL, TRUE); |
| 364 | |
| 365 | while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL)) |
| 366 | { |
| 367 | struct { IMAGEHLP_SYMBOL sym; string n; } si = { { sizeof( IMAGEHLP_SYMBOL ), 0, 0, 0, sizeof(string) } }; |
| 368 | IMAGEHLP_LINE li = { sizeof( IMAGEHLP_LINE ) }; |
| 369 | DWORD off; |
| 370 | if(SymGetSymFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &off, &si.sym) && SymGetLineFromAddr(GetCurrentProcess(), (DWORD)sf.AddrPC.Offset, &off, &li)) |
| 371 | { |
| 372 | char *del = strrchr(li.FileName, '\\'); |
| 373 | formatstring(t)("%s - %s [%d]\n", si.sym.Name, del ? del + 1 : li.FileName, li.LineNumber); |
| 374 | concatstring(out, t); |
| 375 | } |
| 376 | } |
| 377 | #if !defined(STANDALONE) |
| 378 | if(clientlogfile) clientlogfile->printf("%s\n", out); |
| 379 | #endif |
| 380 | fatal("%s", out); |
| 381 | } |
| 382 | #elif defined(linux) || defined(__linux) || defined(__linux__) |
| 383 | |
| 384 | #include <execinfo.h> |
no test coverage detected