#include #include #include #include #define MAX_SYMBOLNAME 512 void sigsegv(int sig) { HANDLE currentProc, currentThread; CONTEXT threadContext; STACKFRAME stackInfo; PIMAGEHLP_SYMBOL pSym; char buf[512]; int framenum; DWORD offset; printf("Crashed! Build %s/%s\n", __DATE__, __TIME__); // todo: also use GetCurrent*Id for DWORD to print currentProc = GetCurrentProcess(); currentThread = GetCurrentThread(); if (!GetThreadContext(currentThread, &threadContext)) { printf("couldn't get thread context\n"); return; } memset(&stackInfo, 0, sizeof(stackInfo)); stackInfo.AddrPC.Offset = threadContext.Eip; stackInfo.AddrStack.Offset = threadContext.Esp; stackInfo.AddrFrame.Offset = threadContext.Ebp; // FIXME: probably shouldn't assume this. bleh. stackInfo.AddrPC.Mode = AddrModeFlat; stackInfo.AddrStack.Mode = AddrModeFlat; stackInfo.AddrFrame.Mode = AddrModeFlat; // slow if (!SymInitialize(currentProc, NULL, FALSE)) { printf("SymInitialize failed: %ld\n", GetLastError()); exit(1); } pSym = GlobalAlloc(GMEM_FIXED, sizeof(IMAGEHLP_SYMBOL) + MAX_SYMBOLNAME); pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); pSym->MaxNameLength = MAX_SYMBOLNAME; for (framenum = 0; ; framenum++) { if (!StackWalk(IMAGE_FILE_MACHINE_I386, currentProc, currentThread, &stackInfo, &threadContext, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL)) { printf("StackWalk failed: %ld\n", GetLastError()); break; } if (stackInfo.AddrFrame.Offset == 0) { printf("AddrFrame.Offset == 0\n"); break; } printf("#%d %08lx %08lx %08lx %08lx: ", framenum, stackInfo.AddrPC.Offset, stackInfo.AddrReturn.Offset, stackInfo.AddrFrame.Offset, stackInfo.AddrStack.Offset); if (stackInfo.AddrPC.Offset == 0) printf("???"); else { if (!SymGetSymFromAddr(currentProc, stackInfo.AddrPC.Offset, &offset, pSym)) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL); printf("??? failed to get symbol name (%s)", buf); } else printf("Symbol: %s<%lx>", pSym->Name, offset); } printf("\n"); } SymCleanup(currentProc); GlobalFree(pSym); //&threadContext, exit(1); } int main(int argc, char *argv[]) { char *null = NULL; int foo; signal(SIGSEGV, sigsegv); foo = *null; return 0; }