// Called from MyApp() immediately upon entry to MyApp::OnInit() void OCPNPlatform::Initialize_1( void ) { #ifdef OCPN_USE_CRASHRPT #ifndef _DEBUG // Install Windows crash reporting CR_INSTALL_INFO info; memset(&info, 0, sizeof(CR_INSTALL_INFO)); info.cb = sizeof(CR_INSTALL_INFO); info.pszAppName = _T("OpenCPN"); wxString version_crash = str_version_major + _T(".") + str_version_minor + _T(".") + str_version_patch; info.pszAppVersion = version_crash.c_str(); int type = MiniDumpWithDataSegs; // Include the data sections from all loaded modules. // This results in the inclusion of global variables type |= MiniDumpNormal;// | MiniDumpWithPrivateReadWriteMemory | MiniDumpWithIndirectlyReferencedMemory; info.uMiniDumpType = (MINIDUMP_TYPE)type; // Install all available exception handlers.... info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS; // Except memory allocation failures info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER; // Allow user to attach files info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES; // Allow user to add more info info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS; // URL for sending error reports over HTTP. if(g_bEmailCrashReport){ info.pszEmailTo = _T("*****@*****.**"); info.pszSmtpProxy = _T("mail.bigdumboat.com:587"); info.pszUrl = _T("http://bigdumboat.com/crashrpt/ocpn_crashrpt.php"); info.uPriorities[CR_HTTP] = 1; // First try send report over HTTP } else{ info.dwFlags |= CR_INST_DONT_SEND_REPORT; info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY; // don't send at all } info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY; // Second try send report over SMTP info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; //1; // Third try send report over Simple MAPI wxStandardPaths& crash_std_path = g_Platform->GetStdPaths(); wxString crash_rpt_save_locn = crash_std_path.GetConfigDir(); if( g_bportable ) { wxFileName exec_path_crash( crash_std_path.GetExecutablePath() ); crash_rpt_save_locn = exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ); } wxString locn = crash_rpt_save_locn + _T("\\CrashReports"); if(!wxDirExists( locn ) ) wxMkdir( locn ); if(wxDirExists( locn ) ){ wxCharBuffer buf = locn.ToUTF8(); wchar_t wlocn[256]; if(buf && (locn.Length() < sizeof(wlocn)) ){ MultiByteToWideChar( 0, 0, buf.data(), -1, wlocn, sizeof(wlocn)-1); info.pszErrorReportSaveDir = (LPCWSTR)wlocn; } } // Provide privacy policy URL wxFileName exec_path_crash( crash_std_path.GetExecutablePath() ); wxString policy_file = exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ); policy_file += _T("PrivacyPolicy.txt"); policy_file.Prepend(_T("file:")); info.pszPrivacyPolicyURL = policy_file.c_str();; int nResult = crInstall(&info); if(nResult!=0) { TCHAR buff[256]; crGetLastErrorMsg(buff, 256); MessageBox(NULL, buff, _T("crInstall error, Crash Reporting disabled."), MB_OK); } // Establish the crash callback function crSetCrashCallback( CrashCallback, NULL ); // Take screenshot of the app window at the moment of crash crAddScreenshot2(CR_AS_PROCESS_WINDOWS|CR_AS_USE_JPEG_FORMAT, 95); // Mark some files to add to the crash report wxString home_data_crash = crash_std_path.GetConfigDir(); if( g_bportable ) { wxFileName f( crash_std_path.GetExecutablePath() ); home_data_crash = f.GetPath(); } appendOSDirSlash( &home_data_crash ); wxString config_crash = _T("opencpn.ini"); config_crash.Prepend( home_data_crash ); crAddFile2( config_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE ); wxString log_crash = _T("opencpn.log"); log_crash.Prepend( home_data_crash ); crAddFile2( log_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE ); #endif #endif #ifdef LINUX_CRASHRPT #if wxUSE_ON_FATAL_EXCEPTION // fatal exceptions handling wxHandleFatalExceptions (true); #endif #endif #ifdef __WXMSW__ // Invoke my own handler for failures of malloc/new _set_new_handler( MyNewHandler ); // configure malloc to call the New failure handler on failure _set_new_mode(1); #endif // On MSW, force the entire process to run on one CPU core only // This resolves some difficulty with wxThread syncronization #if 0 #ifdef __WXMSW__ //Gets the current process handle HANDLE hProc = GetCurrentProcess(); DWORD procMask; DWORD sysMask; HANDLE hDup; DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS ); //Gets the current process affinity mask GetProcessAffinityMask( hDup, &procMask, &sysMask ); // Take a simple approach, and assume up to 4 processors DWORD newMask; if( ( procMask & 1 ) == 1 ) newMask = 1; else if( ( procMask & 2 ) == 2 ) newMask = 2; else if( ( procMask & 4 ) == 4 ) newMask = 4; else if( ( procMask & 8 ) == 8 ) newMask = 8; //Set te affinity mask for the process BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask ); if( res == 0 ) { //Error setting affinity mask!! } #endif #endif #ifdef __WXMSW__ // Handle any Floating Point Exceptions which may leak thru from other // processes. The exception filter is in cutil.c // Seems to only happen for W98 wxPlatformInfo Platform; if( Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X ) SetUnhandledExceptionFilter (&MyUnhandledExceptionFilter); #endif #ifdef __WXMSW__ // _CrtSetBreakAlloc(25503); #endif #ifndef __WXMSW__ // Setup Linux SIGNAL handling, for external program control // Build the sigaction structure sa_all.sa_handler = catch_signals;// point to my handler sigemptyset(&sa_all.sa_mask);// make the blocking set // empty, so that all // other signals will be // unblocked during my handler sa_all.sa_flags = 0; sigaction(SIGUSR1, NULL, &sa_all_old);// save existing action for this signal // Register my request for some signals sigaction(SIGUSR1, &sa_all, NULL); sigaction(SIGUSR1, NULL, &sa_all_old);// inspect existing action for this signal sigaction(SIGTERM, &sa_all, NULL); sigaction(SIGTERM, NULL, &sa_all_old); #endif }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) { // Define CrashRpt configuration parameters CR_INSTALL_INFO info; memset(&info, 0, sizeof(CR_INSTALL_INFO)); info.cb = sizeof(CR_INSTALL_INFO); info.pszAppName = _T("crashtestdummy"); info.pszAppVersion = _T("1.0.0"); info.pszEmailSubject = _T("Error Report"); info.pszEmailTo = _T("*****@*****.**"); info.uPriorities[CR_HTTP] = 3; // First try send report over HTTP info.uPriorities[CR_SMTP] = 2; // Second try send report over SMTP info.uPriorities[CR_SMAPI] = 1; // Third try send report over Simple MAPI // Install all available exception handlers info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS; // Restart the app on crash info.dwFlags |= CR_INST_APP_RESTART; info.dwFlags |= CR_INST_SEND_QUEUED_REPORTS; info.pszRestartCmdLine = _T("/restart"); // Define the Privacy Policy URL info.pszPrivacyPolicyURL = _T("http://myapp.com/privacypolicy.html"); // Install crash reporting int nResult = crInstall(&info); if(nResult!=0) { // Something goes wrong. Get error message. TCHAR szErrorMsg[512] = _T(""); crGetLastErrorMsg(szErrorMsg, 512); _tprintf_s(_T("%s\n"), szErrorMsg); return 1; } // Set crash callback function crSetCrashCallback(CrashCallback, NULL); // Add our log file to the error report crAddFile2(_T("log.txt"), NULL, _T("Log File"), CR_AF_MAKE_FILE_COPY); // We want the screenshot of the entire desktop is to be added on crash crAddScreenshot2(CR_AS_VIRTUAL_SCREEN, 0); // Add a named property that means what graphics adapter is // installed on user's machine crAddProperty(_T("VideoCard"), _T("nVidia GeForce 8600 GTS")); HRESULT hRes = ::CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call instead to // make the EXE free threaded. This means that calls come in on a random RPC thread. // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); ATLASSERT(SUCCEEDED(hRes)); // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used ::DefWindowProc(NULL, 0, 0, 0L); AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls hRes = _Module.Init(NULL, hInstance); ATLASSERT(SUCCEEDED(hRes)); int nRet = Run(lpstrCmdLine, nCmdShow); _Module.Term(); ::CoUninitialize(); errno_t err = _tfopen_s(&g_hLog, _T("log.txt"), _T("wt")); if(err!=0 || g_hLog==NULL) { _tprintf_s(_T("Error opening log.txt\n")); return 1; // Couldn't open log file } log_write(_T("Started successfully\n")); // There is a hidden error in the main() function // Call of _tprintf_s with NULL parameter TCHAR* szFormatString = NULL; _tprintf_s(szFormatString); // Close the log file if(g_hLog!=NULL) { fclose(g_hLog); g_hLog = NULL;// Clean up handle } // Uninitialize CrashRpt before exiting the main function crUninstall(); return nRet; }