void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) { STACKFRAME callStack; BOOL bResult; HANDLE hProcess = GetCurrentProcess(); // If it's not this thread, let's suspend it, and resume it at the end if ( hThread != GetCurrentThread() ) if (SuspendThread( hThread ) == -1) { // whaaat ?! etfprint(file, "Call stack info failed\n"); return; } ::ZeroMemory( &callStack, sizeof(callStack) ); callStack.AddrPC.Offset = eip; callStack.AddrStack.Offset = esp; callStack.AddrFrame.Offset = ebp; callStack.AddrPC.Mode = AddrModeFlat; callStack.AddrStack.Mode = AddrModeFlat; callStack.AddrFrame.Mode = AddrModeFlat; etfprint(file, "Call stack info: \n"); etfprint(file, lpszMessage); PrintFunctionAndSourceInfo(file, callStack); for (ULONG index = 0; ; index++) { bResult = StackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &callStack, nullptr, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr); if (index == 0) continue; if (!bResult || callStack.AddrFrame.Offset == 0) break; PrintFunctionAndSourceInfo(file, callStack); } if (hThread != GetCurrentThread()) ResumeThread(hThread); }
void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) { TCHAR symInfo[BUFFERSIZE] = _T("?"); TCHAR srcInfo[BUFFERSIZE] = _T("?"); GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); etfprint(file, " " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); }
//Has no error handling. //I think that if an error occurs here there's no way to handle it anyway. LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS e) { //EnterCriticalSection(&g_uefcs); File::IOFile file("exceptioninfo.txt", "a"); file.Seek(0, SEEK_END); etfprint(file.GetHandle(), "\n"); //etfprint(file, g_buildtime); //etfprint(file, "\n"); //dumpCurrentDate(file); etfprintf(file.GetHandle(), "Unhandled Exception\n Code: 0x%08X\n", e->ExceptionRecord->ExceptionCode); STACKTRACE2(file.GetHandle(), e->ContextRecord->Rip, e->ContextRecord->Rsp, e->ContextRecord->Rbp); file.Close(); _flushall(); //LeaveCriticalSection(&g_uefcs); return EXCEPTION_CONTINUE_SEARCH; }