#pragma once #include #include #include //#include "Logger.h" #pragma comment(lib, "dbghelp.lib") class DiosTempOutputFile { HANDLE m_FileHandle; public: DiosTempOutputFile() { m_FileHandle = INVALID_HANDLE_VALUE; }; virtual ~DiosTempOutputFile(void) { Close(); }; bool Create(const char *pszFile) { //new one m_FileHandle = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (m_FileHandle == INVALID_HANDLE_VALUE) { throw "ERROR AT Create FILE"; return false; } return true; }; bool Open(const char *pszFile) { m_FileHandle = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (m_FileHandle == INVALID_HANDLE_VALUE) { throw "ERROR AT Open FILE"; return false; } return true; }; void Close() { if (m_FileHandle != INVALID_HANDLE_VALUE) { CloseHandle(m_FileHandle); m_FileHandle = INVALID_HANDLE_VALUE; } }; bool is_open() { return (m_FileHandle != INVALID_HANDLE_VALUE); }; DiosTempOutputFile& operator << (DWORD Val) { if (m_FileHandle != INVALID_HANDLE_VALUE) { if (SetFilePointer(m_FileHandle, 0, 0, FILE_END) != INVALID_SET_FILE_POINTER) { DWORD returnedLenth = 0; char szVal[16]; sprintf_s(szVal, 16, "%u", Val); if (WriteFile(m_FileHandle, szVal, (DWORD)strlen(szVal), &returnedLenth, 0) == FALSE) { printf("\n\nERROR AT WRITE FILE:\n\n"); throw "ERROR AT WRITE FILE"; } return (*this); } } throw "ERROR AT WRITE FILE ON EMPTY HANDLE"; return (*this); }; DiosTempOutputFile& operator << (const char* pVal) { if (m_FileHandle != INVALID_HANDLE_VALUE) { if (SetFilePointer(m_FileHandle, 0, 0, FILE_END) != INVALID_SET_FILE_POINTER) { DWORD returnedLenth = 0; if (WriteFile(m_FileHandle, pVal, (DWORD)strlen(pVal), &returnedLenth, 0) == FALSE) { printf("\n\nERROR AT WRITE FILE:\n\n"); throw "ERROR AT WRITE FILE"; } return (*this); } } throw "ERROR AT WRITE FILE ON EMPTY HANDLE"; return (*this); }; }; class StackTrace { private: static const int m_MaxFrameCount = 62; int m_FrameCount; void* m_Frames[m_MaxFrameCount]; HANDLE m_Mutex; //string GetCurTime() //{ // SYSTEMTIME st; // GetLocalTime(&st); // string Context; // printf("hit At %4d-%2d-%2d %2d:%2d:%2d.%3d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); //} public: StackTrace() { m_Mutex = CreateMutex(0, 0, 0); m_FrameCount = CaptureStackBackTrace(1, m_MaxFrameCount, m_Frames, NULL); Print(); } ~StackTrace() { CloseHandle(m_Mutex); }; void Print() { HANDLE process = GetCurrentProcess(); SymSetOptions(SYMOPT_LOAD_LINES); // set symbol option to load the source code lines SymInitialize(process, NULL, TRUE); // init symbol char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; // define the PSYMBOL_INFO PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; IMAGEHLP_LINE64 line; // define the IMAGEHLP_LINE64 line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); DiosTempOutputFile Outfile; WaitForSingleObject(m_Mutex, INFINITE); Outfile.Open("StackTrace.log"); Outfile << "StackTrace Entry\n"; for (int i = 0; i < m_FrameCount; i++) { DWORD64 dw64Displacement; SymFromAddr(process, (DWORD64)(m_Frames[i]), &dw64Displacement, symbol); // get symbol info std::cout << symbol->Name; DWORD dwDisplacement; if (SymGetLineFromAddr64(process, (DWORD64)(m_Frames[i]), &dwDisplacement, &line)) // get line info { std::cout << symbol->Name << ", " << line.FileName << ", line " << line.LineNumber; { SYSTEMTIME st; GetLocalTime(&st); char szTime[128]; sprintf_s(szTime, 64, "%4d-%2d-%2d %2d:%2d:%2d.%3d PID[%0x08]TID[%0x08]", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, GetCurrentProcessId(), GetCurrentThreadId()); //TPRINTA_ERROR("%s,%s,line:%d", symbol->Name, line.FileName, line.LineNumber); Outfile << szTime << symbol->Name << ", " << line.FileName << ", line " << line.LineNumber << "\n"; } } std::cout << std::endl; } Outfile << "StackTrace Exit\n"; SymCleanup(process); ReleaseMutex(m_Mutex); } };