void CIWinSyncDlg::SetupLogging() { m_bLoggingEnabled = FALSE; //Read The Current Log Path ReadRegStringValue(_T("Software\\IWinSync"), _T("LogPath"),&m_pszLogPath); if(m_pszLogPath !=NULL) { _stprintf_s(m_pszConflictLogPath,MAX_PATH,_T("%s\\%s"),m_pszLogPath,CONFLICT_LOG_NAME); _stprintf_s(m_pszAppLogPath,MAX_PATH,_T("%s"),m_pszLogPath); } m_dwLogLevel = ReadRegDWordValue(_T("Software\\IWinSync"), _T("LogLevel")); int size_needed = WideCharToMultiByte(CP_UTF8, 0, m_pszLogPath, (int)_tcslen(m_pszLogPath), NULL, 0, NULL, NULL); std::string strLogPath( size_needed, 0 ); WideCharToMultiByte(CP_UTF8, 0, m_pszLogPath, (int)_tcslen(m_pszLogPath), &strLogPath[0], size_needed, NULL, NULL); m_pLogger = new g2LogWorker(APP_LOG_NAME, strLogPath); g_iLoggingLevel = m_dwLogLevel; g2::initializeLogging(m_pLogger); m_bLoggingEnabled = TRUE; }
void CExceptionHandler::WriteExceptionReport() #endif { // Get the current time and date time_t t = time(NULL); const struct tm * tm = localtime(&t); // Get the 'crashinfo' directory path String strPath(SharedUtility::GetAbsolutePath("crashinfo")); // Create the 'crashinfo' directory if needed if(!SharedUtility::Exists(strPath)) SharedUtility::CreateDirectory(strPath); // Append the client or server string to the path #ifdef _SERVER strPath.Append("\\Server"); #else strPath.Append("\\Client"); #endif // Append the operating system string to the path strPath.Append("-" OS_STRING); // Append the version, date and time to the path strPath.AppendF("-" MOD_VERSION_STRING "-%04d.%02d.%02d-%02d.%02d.%02d", (tm->tm_year + 1900), (tm->tm_mon + 1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); // Get the log file path String strLogPath("%s.log", strPath.Get()); // Open the log file FILE * fFile = fopen(strLogPath, "w"); // Did the log file open successfully? if(fFile) { String strReportData; // Write the unhandled exception report start notice to the log file fprintf(fFile, "-- Unhandled Exception Report Start --\n"); #ifdef WIN32 // Write the exception code and exception code string to the log file strReportData.AppendF("Exception code: 0x%p (%s)\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionCodeToString(ExceptionInfo->ExceptionRecord->ExceptionCode)); // Write the exception address to the log file #ifndef _SERVER strReportData.AppendF("Exception address: 0x%p (Game base: 0x%p)\n", ExceptionInfo->ExceptionRecord->ExceptionAddress, CGame::GetBase()); strReportData.AppendF("Exception real-add: 0x%p / 0x%p\n", ((int)ExceptionInfo->ExceptionRecord->ExceptionAddress-CGame::GetBase()), (CGame::GetBase()-(int)ExceptionInfo->ExceptionRecord->ExceptionAddress)); #else strReportData.AppendF("Exception address: 0x%p\n", ExceptionInfo->ExceptionRecord->ExceptionAddress); #endif // Create a tool help 32 process snapshot HANDLE hModuleSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); if(hModuleSnapShot) { MODULEENTRY32 ModuleEntry; ModuleEntry.dwSize = sizeof(ModuleEntry); if(Module32First(hModuleSnapShot, &ModuleEntry)) { // Enumerate through all modules while(Module32Next(hModuleSnapShot, &ModuleEntry)) { // See if exception was within this module if((ExceptionInfo->ContextRecord->Eip >= (DWORD)ModuleEntry.modBaseAddr) && (ExceptionInfo->ContextRecord->Eip <= ((DWORD)ModuleEntry.modBaseAddr + ModuleEntry.modBaseSize))) { strReportData.AppendF("Exception module: %s (+0x%p)\n", ModuleEntry.szModule, (ExceptionInfo->ContextRecord->Eip - (DWORD)ModuleEntry.modBaseAddr)); break; } } } } // Write the registers segment header strReportData.AppendF("Exception registers: \n"); // If we have segments context information then write it to the log file if(ExceptionInfo->ContextRecord->ContextFlags & CONTEXT_SEGMENTS) { strReportData.AppendF("GS=0x%p FS=0x%p ES=0x%p DS=0x%p\n", ExceptionInfo->ContextRecord->SegGs, ExceptionInfo->ContextRecord->SegFs, ExceptionInfo->ContextRecord->SegEs, ExceptionInfo->ContextRecord->SegDs); } // If we have integer context information then write it to the log file if(ExceptionInfo->ContextRecord->ContextFlags & CONTEXT_INTEGER) { strReportData.AppendF("EDI=0x%p ESI=0x%p EBX=0x%p EDX=0x%p\n", ExceptionInfo->ContextRecord->Edi, ExceptionInfo->ContextRecord->Esi, ExceptionInfo->ContextRecord->Ebx, ExceptionInfo->ContextRecord->Edx); strReportData.AppendF("ECX=0x%p EAX=0x%p\n", ExceptionInfo->ContextRecord->Ecx, ExceptionInfo->ContextRecord->Eax); } // If we have control context information then write it to the log file if(ExceptionInfo->ContextRecord->ContextFlags & CONTEXT_CONTROL) { strReportData.AppendF("EBP=0x%p EIP=0x%p CS=0x%p EFLAGS=0x%p\n", ExceptionInfo->ContextRecord->Ebp, ExceptionInfo->ContextRecord->Eip, ExceptionInfo->ContextRecord->SegCs, ExceptionInfo->ContextRecord->EFlags); strReportData.AppendF("ESP=0x%p SS=0x%p\n", ExceptionInfo->ContextRecord->Esp, ExceptionInfo->ContextRecord->SegSs); } #else void * pArray[50]; int iSize = backtrace(pArray, 50); char ** szMessages = backtrace_symbols(pArray, iSize); for(int i = 0; i < iSize && (szMessages[i] != NULL); i++) strReportData.AppendF("[Backtrace %d]: %s\n", i, szMessages[i]); #endif // If we have a callback call it if(m_pfnCallback) m_pfnCallback(strReportData); // Print the report data to the log file fprintf(fFile, strReportData.Get()); // Write the unhandled exception report end notice to the log file fprintf(fFile, "--Unhandled Exception Report End --\n"); // Close the log file fclose(fFile); } else CLogFile::Printf("Failed to open the crash log file."); #ifdef WIN32 // Get the minidump file path String strMiniDumpPath("%s.dmp", strPath.Get()); // Open the minidump file HANDLE hFile = CreateFileA(strMiniDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL , NULL); // Did the minidump file open successfully? if(hFile) { // Create the minidump exception information MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; exceptionInfo.ThreadId = GetCurrentThreadId(); exceptionInfo.ExceptionPointers = ExceptionInfo; exceptionInfo.ClientPointers = FALSE; // Write the minidump to the minidump file if(!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &exceptionInfo, NULL, NULL)) CLogFile::Printf("Failed to write the minidump file."); // Close the minidump file CloseHandle(hFile); } else CLogFile::Printf("Failed to open the minidump file."); #endif // Print a message in the log file CLogFile::Printf("IV:MP has crashed. Please see %s for more information.", strLogPath.Get()); }