diff options
Diffstat (limited to 'indra/newview/llappviewerwin32.cpp')
-rw-r--r--[-rwxr-xr-x] | indra/newview/llappviewerwin32.cpp | 173 |
1 files changed, 130 insertions, 43 deletions
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 2764025d75..57fb84bbf1 100755..100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -29,11 +29,12 @@ #ifdef INCLUDE_VLD #include "vld.h" #endif +#include "llwin32headers.h" -#include "llappviewerwin32.h" +#include "llwindowwin32.h" // *FIX: for setting gIconResource. +#include "llappviewerwin32.h" -#include "llwindowwin32.h" // *FIX: for setting gIconResource. #include "llgl.h" #include "res/resource.h" // *FIX: for setting gIconResource. @@ -52,7 +53,6 @@ #include <stdlib.h> #include "llweb.h" -#include "llsecondlifeurls.h" #include "llviewernetwork.h" #include "llmd5.h" @@ -65,6 +65,33 @@ #include "llwindebug.h" #endif +#include "stringize.h" + +#include <exception> +namespace +{ + void (*gOldTerminateHandler)() = NULL; +} + +static void exceptionTerminateHandler() +{ + // reinstall default terminate() handler in case we re-terminate. + if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); + // treat this like a regular viewer crash, with nice stacktrace etc. + long *null_ptr; + null_ptr = 0; + *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. + //LLAppViewer::handleViewerCrash(); + // we've probably been killed-off before now, but... + gOldTerminateHandler(); // call old terminate() handler +} + +LONG WINAPI catchallCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/) +{ + LL_WARNS() << "Hit last ditch-effort attempt to catch crash." << LL_ENDL; + exceptionTerminateHandler(); + return 0; +} // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert @@ -73,7 +100,7 @@ extern "C" { void _wassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) { - llerrs << _Message << llendl; + LL_ERRS() << _Message << LL_ENDL; } } #endif @@ -89,7 +116,7 @@ void nvapi_error(NvAPI_Status status) { NvAPI_ShortString szDesc = {0}; NvAPI_GetErrorMessage(status, szDesc); - llwarns << szDesc << llendl; + LL_WARNS() << szDesc << LL_ENDL; //should always trigger when asserts are enabled //llassert(status == NVAPI_OK); @@ -236,8 +263,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine); + gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); +#if LL_SEND_CRASH_REPORTS + // ::SetUnhandledExceptionFilter(catchallCrashHandler); +#endif + // Set a debug info flag to indicate if multiple instances are running. bool found_other_instance = !create_app_mutex(); gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); @@ -245,7 +278,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, bool ok = viewer_app_ptr->init(); if(!ok) { - llwarns << "Application init failed." << llendl; + LL_WARNS() << "Application init failed." << LL_ENDL; return -1; } @@ -273,12 +306,12 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // Have to wait until after logging is initialized to display LFH info if (num_heaps > 0) { - llinfos << "Attempted to enable LFH for " << num_heaps << " heaps." << llendl; + LL_INFOS() << "Attempted to enable LFH for " << num_heaps << " heaps." << LL_ENDL; for(S32 i = 0; i < num_heaps; i++) { if (heap_enable_lfh_error[i]) { - llinfos << " Failed to enable LFH for heap: " << i << " Error: " << heap_enable_lfh_error[i] << llendl; + LL_INFOS() << " Failed to enable LFH for heap: " << i << " Error: " << heap_enable_lfh_error[i] << LL_ENDL; } } } @@ -297,14 +330,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // app cleanup if there was a problem. // #if WINDOWS_CRT_MEM_CHECKS - llinfos << "CRT Checking memory:" << llendflush; + LL_INFOS() << "CRT Checking memory:" << LL_ENDL; if (!_CrtCheckMemory()) { - llwarns << "_CrtCheckMemory() failed at prior to cleanup!" << llendflush; + LL_WARNS() << "_CrtCheckMemory() failed at prior to cleanup!" << LL_ENDL; } else { - llinfos << " No corruption detected." << llendflush; + LL_INFOS() << " No corruption detected." << LL_ENDL; } #endif @@ -313,14 +346,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, viewer_app_ptr->cleanup(); #if WINDOWS_CRT_MEM_CHECKS - llinfos << "CRT Checking memory:" << llendflush; + LL_INFOS() << "CRT Checking memory:" << LL_ENDL; if (!_CrtCheckMemory()) { - llwarns << "_CrtCheckMemory() failed after cleanup!" << llendflush; + LL_WARNS() << "_CrtCheckMemory() failed after cleanup!" << LL_ENDL; } else { - llinfos << " No corruption detected." << llendflush; + LL_INFOS() << " No corruption detected." << LL_ENDL; } #endif @@ -391,11 +424,11 @@ void LLAppViewerWin32::disableWinErrorReporting() if( 0 == pAddERExcludedApplicationA( executable_name ) ) { U32 error_code = GetLastError(); - llinfos << "AddERExcludedApplication() failed with error code " << error_code << llendl; + LL_INFOS() << "AddERExcludedApplication() failed with error code " << error_code << LL_ENDL; } else { - llinfos << "AddERExcludedApplication() success for " << executable_name << llendl; + LL_INFOS() << "AddERExcludedApplication() success for " << executable_name << LL_ENDL; } } FreeLibrary( fault_rep_dll_handle ); @@ -405,7 +438,7 @@ void LLAppViewerWin32::disableWinErrorReporting() const S32 MAX_CONSOLE_LINES = 500; -void create_console() +static bool create_console() { int h_con_handle; long l_std_handle; @@ -414,7 +447,7 @@ void create_console() FILE *fp; // allocate a console for this app - AllocConsole(); + const bool isConsoleAllocated = AllocConsole(); // set the screen buffer to be big enough to let us scroll text GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); @@ -426,7 +459,7 @@ void create_console() h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); if (h_con_handle == -1) { - llwarns << "create_console() failed to open stdout handle" << llendl; + LL_WARNS() << "create_console() failed to open stdout handle" << LL_ENDL; } else { @@ -440,7 +473,7 @@ void create_console() h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); if (h_con_handle == -1) { - llwarns << "create_console() failed to open stdin handle" << llendl; + LL_WARNS() << "create_console() failed to open stdin handle" << LL_ENDL; } else { @@ -454,7 +487,7 @@ void create_console() h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); if (h_con_handle == -1) { - llwarns << "create_console() failed to open stderr handle" << llendl; + LL_WARNS() << "create_console() failed to open stderr handle" << LL_ENDL; } else { @@ -462,10 +495,13 @@ void create_console() *stderr = *fp; setvbuf( stderr, NULL, _IONBF, 0 ); } + + return isConsoleAllocated; } LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) : - mCmdLine(cmd_line) + mCmdLine(cmd_line), + mIsConsoleAllocated(false) { } @@ -481,14 +517,26 @@ bool LLAppViewerWin32::init() // (Don't send our data to Microsoft--at least until we are Logo approved and have a way // of getting the data back from them.) // - // llinfos << "Turning off Windows error reporting." << llendl; + // LL_INFOS() << "Turning off Windows error reporting." << LL_ENDL; disableWinErrorReporting(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLWinDebug::instance().init(); #endif - return LLAppViewer::init(); +#if LL_WINDOWS +#if LL_SEND_CRASH_REPORTS + + + LLAppViewer* pApp = LLAppViewer::instance(); + pApp->initCrashReporting(); + +#endif +#endif + + bool success = LLAppViewer::init(); + + return success; } bool LLAppViewerWin32::cleanup() @@ -497,6 +545,16 @@ bool LLAppViewerWin32::cleanup() gDXHardware.cleanup(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLWinDebug::instance().cleanup(); +#endif + + if (mIsConsoleAllocated) + { + FreeConsole(); + mIsConsoleAllocated = false; + } + return result; } @@ -508,7 +566,7 @@ void LLAppViewerWin32::initLoggingAndGetLastDuration() void LLAppViewerWin32::initConsole() { // pop up debug console - create_console(); + mIsConsoleAllocated = create_console(); return LLAppViewer::initConsole(); } @@ -558,7 +616,7 @@ bool LLAppViewerWin32::initHardwareTest() if (OSBTN_NO== button) { LL_INFOS("AppInit") << "User quitting after failed DirectX 9 detection" << LL_ENDL; - LLWeb::loadURLExternal(DIRECTX_9_URL, false); + LLWeb::loadURLExternal("http://secondlife.com/support/", false); return false; } gWarningSettings.setBOOL("AboutDirectX9", FALSE); @@ -627,26 +685,55 @@ bool LLAppViewerWin32::restoreErrorTrap() //return LLWinDebug::checkExceptionHandler(); } -void LLAppViewerWin32::handleCrashReporting(bool reportFreeze) +void LLAppViewerWin32::initCrashReporting(bool reportFreeze) { + if (isSecondInstance()) return; //BUG-5707 do not start another crash reporter for second instance. + const char* logger_name = "win_crash_logger.exe"; std::string exe_path = gDirUtilp->getExecutableDir(); exe_path += gDirUtilp->getDirDelimiter(); exe_path += logger_name; - const char* arg_str = logger_name; + std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); + std::string appname = gDirUtilp->getExecutableFilename(); - // *NOTE:Mani - win_crash_logger.exe no longer parses command line options. - if(reportFreeze) - { - // Spawn crash logger. - // NEEDS to wait until completion, otherwise log files will get smashed. - _spawnl(_P_WAIT, exe_path.c_str(), arg_str, NULL); - } - else - { - _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL); - } + S32 slen = logdir.length() -1; + S32 end = slen; + while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--; + + if (slen !=end) + { + logdir = logdir.substr(0,end+1); + } + //std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); + //_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL); + std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); + + STARTUPINFO startInfo={sizeof(startInfo)}; + PROCESS_INFORMATION processInfo; + + std::wstring exe_wstr; + exe_wstr=wstringize(exe_path); + + std::wstring arg_wstr; + arg_wstr=wstringize(arg_str); + + LL_INFOS("CrashReport") << "Creating crash reporter process " << exe_path << " with params: " << arg_str << LL_ENDL; + if(CreateProcess(exe_wstr.c_str(), + &arg_wstr[0], // Application arguments + 0, + 0, + FALSE, + CREATE_DEFAULT_ERROR_MODE, + 0, + 0, // Working directory + &startInfo, + &processInfo) == FALSE) + // Could not start application -> call 'GetLastError()' + { + LL_WARNS("CrashReport Launch") << "CreateProcess failed " << GetLastError() << LL_ENDL; + return; + } } //virtual @@ -660,7 +747,7 @@ bool LLAppViewerWin32::sendURLToOtherInstance(const std::string& url) if (other_window != NULL) { - lldebugs << "Found other window with the name '" << getWindowTitle() << "'" << llendl; + LL_DEBUGS() << "Found other window with the name '" << getWindowTitle() << "'" << LL_ENDL; COPYDATASTRUCT cds; const S32 SLURL_MESSAGE_TYPE = 0; cds.dwData = SLURL_MESSAGE_TYPE; @@ -668,8 +755,8 @@ bool LLAppViewerWin32::sendURLToOtherInstance(const std::string& url) cds.lpData = (void*)url.c_str(); LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); - lldebugs << "SendMessage(WM_COPYDATA) to other window '" - << getWindowTitle() << "' returned " << msg_result << llendl; + LL_DEBUGS() << "SendMessage(WM_COPYDATA) to other window '" + << getWindowTitle() << "' returned " << msg_result << LL_ENDL; return true; } return false; @@ -701,7 +788,7 @@ std::string LLAppViewerWin32::generateSerialNumber() } else { - llwarns << "GetVolumeInformation failed" << llendl; + LL_WARNS() << "GetVolumeInformation failed" << LL_ENDL; } return serial_md5; } |