From f648758c2a3da2dd03c8f57e98598c085b2030a6 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 16 Jan 2019 11:05:55 -0500 Subject: SL-10297: Modify LL_ERRS and other deliberate crashes to avoid a common stack frame --- indra/newview/llappviewer.cpp | 89 +++++++------------------------------------ 1 file changed, 14 insertions(+), 75 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a33e978c0a..e6ba3e4f7c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -751,17 +751,6 @@ public: } }; -namespace { -// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide -// this little helper function. -void fast_exit(int rc) -{ - _exit(rc); -} - - -} - bool LLAppViewer::init() { @@ -801,19 +790,6 @@ bool LLAppViewer::init() initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); - - // Although initLoggingAndGetLastDuration() is the right place to mess with - // setFatalFunction(), we can't query gSavedSettings until after - // initConfiguration(). - S32 rc(gSavedSettings.getS32("QAModeTermCode")); - if (rc >= 0) - { - // QAModeTermCode set, terminate with that rc on LL_ERRS. Use - // fast_exit() rather than exit() because normal cleanup depends too - // much on successful startup! - LLError::setFatalFunction(boost::bind(fast_exit, rc)); - } - mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); // Initialize the non-LLCurl libcurl library. Should be called @@ -2120,28 +2096,9 @@ bool LLAppViewer::cleanup() return true; } -// A callback for LL_ERRS() to call during the watchdog error. -void watchdog_llerrs_callback(const std::string &error_string) -{ - gLLErrorActivated = true; - gDebugInfo["FatalMessage"] = error_string; LLAppViewer::instance()->writeDebugInfo(); -#ifdef LL_WINDOWS - RaiseException(0,0,0,0); -#else - raise(SIGQUIT); -#endif -} - -// A callback for the watchdog to call. -void watchdog_killer_callback() -{ - LLError::setFatalFunction(watchdog_llerrs_callback); - LL_ERRS() << "Watchdog killer event" << LL_ENDL; -} - bool LLAppViewer::initThreads() { static const bool enable_threads = true; @@ -2176,24 +2133,6 @@ bool LLAppViewer::initThreads() return true; } -void errorCallback(const std::string &error_string) -{ -#ifndef LL_RELEASE_FOR_DOWNLOAD - OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); -#endif - - //Set the ErrorActivated global so we know to create a marker file - gLLErrorActivated = true; - - gDebugInfo["FatalMessage"] = error_string; - // We're not already crashing -- we simply *intend* to crash. Since we - // haven't actually trashed anything yet, we can afford to write the whole - // static info file. - LLAppViewer::instance()->writeDebugInfo(); - - LLError::crashAndLoop(error_string); -} - void LLAppViewer::initLoggingAndGetLastDuration() { // @@ -2202,8 +2141,6 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "") ); - LLError::setFatalFunction(errorCallback); - //LLError::setTimeFunction(getRuntime); // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, @@ -2952,6 +2889,7 @@ bool LLAppViewer::initWindow() // Need to load feature table before cheking to start watchdog. bool use_watchdog = false; int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); + if (watchdog_enabled_setting == -1) { use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); @@ -2962,11 +2900,16 @@ bool LLAppViewer::initWindow() use_watchdog = bool(watchdog_enabled_setting); } + LL_INFOS("AppInit") << "watchdog" + << (use_watchdog ? " " : " NOT ") + << "enabled" + << " (setting = " << watchdog_enabled_setting << ")" + << LL_ENDL; + if (use_watchdog) { - LLWatchdog::getInstance()->init(watchdog_killer_callback); + LLWatchdog::getInstance()->init(); } - LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL; LLNotificationsUI::LLNotificationManager::getInstance(); @@ -3409,12 +3352,10 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["MainloopThreadID"] = (S32)thread_id; #endif - // "CrashNotHandled" is set here, while things are running well, - // in case of a freeze. If there is a freeze, the crash logger will be launched - // and can read this value from the debug_info.log. - // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, - // then the value of "CrashNotHandled" will be set to true. - gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; + // "CrashNotHandled" is obsolete; it used (not very successsfully) + // to try to distinguish crashes from freezes + gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; + gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); // Insert crash host url (url to post crash log to) if configured. This insures // that the crash report will go to the proper location in the case of a @@ -3567,10 +3508,6 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); } - // The crash is being handled here so set this value to false. - // Otherwise the crash logger will think this crash was a freeze. - gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; - //Write out the crash status file //Use marker file style setup, as that's the simplest, especially since //we're already in a crash situation @@ -3642,6 +3579,8 @@ void LLAppViewer::handleViewerCrash() if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]); + gDebugInfo["Dynamic"]["FatalMessage"] = LLError::getFatalMessage(); + // Close the debug file pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead. } -- cgit v1.2.3 From fc90cad4f366c4bb85add832a2fa8137b1f120ff Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 16 Jan 2019 16:42:34 -0500 Subject: change the default crash type from "freeze" to "other" --- indra/newview/llappviewer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e6ba3e4f7c..1fda07edd6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3508,6 +3508,10 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); } + // The crash is being handled here so set this value to false. + // Otherwise the crash logger will think this crash was a freeze. + gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; + //Write out the crash status file //Use marker file style setup, as that's the simplest, especially since //we're already in a crash situation @@ -3680,8 +3684,11 @@ void LLAppViewer::processMarkerFiles() { // the file existed, is ours, and matched our version, so we can report on what it says LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL; +# if LL_BUGSPLAT + gLastExecEvent = LAST_EXEC_OTHER_CRASH; +# else gLastExecEvent = LAST_EXEC_FROZE; - +# endif } else { -- cgit v1.2.3 From e409c0492f1b1ce63606c0b693c92cdb36dcc28b Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Sat, 2 Mar 2019 11:58:11 -0500 Subject: convert to an explicit USE_BUGSPLAT switch in cmake, revise LL_ERRS approach --- indra/newview/llappviewer.cpp | 59 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 7 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1fda07edd6..f9ee22d20a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -719,14 +719,14 @@ LLAppViewer::LLAppViewer() // from the previous viewer run between this constructor call and the // init() call, which will overwrite the static_debug_info.log file for // THIS run. So setDebugFileNames() early. -#if LL_BUGSPLAT +# ifdef LL_BUGSPLAT // MAINT-8917: don't create a dump directory just for the // static_debug_info.log file std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); -#else // ! LL_BUGSPLAT +# else // ! LL_BUGSPLAT // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues. std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); -#endif // ! LL_BUGSPLAT +# endif // ! LL_BUGSPLAT mDumpPath = logdir; setMiniDumpDir(logdir); setDebugFileNames(logdir); @@ -751,6 +751,16 @@ public: } }; +namespace { +// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide +// this little helper function. +void fast_exit(int rc) +{ + _exit(rc); +} + + +} bool LLAppViewer::init() { @@ -790,6 +800,18 @@ bool LLAppViewer::init() initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); + // Although initLoggingAndGetLastDuration() is the right place to mess with + // overrideCrashOnError(), we can't query gSavedSettings until after + // initConfiguration(). + S32 rc(gSavedSettings.getS32("QAModeTermCode")); + if (rc >= 0) + { + // QAModeTermCode set, terminate with that rc on LL_ERRS. Use + // fast_exit() rather than exit() because normal cleanup depends too + // much on successful startup! + LLError::overrideCrashOnError(boost::bind(fast_exit, rc)); + } + mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); // Initialize the non-LLCurl libcurl library. Should be called @@ -2096,9 +2118,6 @@ bool LLAppViewer::cleanup() return true; } - gDebugInfo["FatalMessage"] = error_string; - LLAppViewer::instance()->writeDebugInfo(); - bool LLAppViewer::initThreads() { static const bool enable_threads = true; @@ -2133,6 +2152,24 @@ bool LLAppViewer::initThreads() return true; } +#ifndef LL_BUGSPLAT +void errorCallback(const std::string &error_string) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD + OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); +#endif + + //Set the ErrorActivated global so we know to create a marker file + gLLErrorActivated = true; + + gDebugInfo["FatalMessage"] = error_string; + // We're not already crashing -- we simply *intend* to crash. Since we + // haven't actually trashed anything yet, we can afford to write the whole + // static info file. + LLAppViewer::instance()->writeDebugInfo(); +} +#endif // ! LL_BUGSPLAT + void LLAppViewer::initLoggingAndGetLastDuration() { // @@ -2889,7 +2926,6 @@ bool LLAppViewer::initWindow() // Need to load feature table before cheking to start watchdog. bool use_watchdog = false; int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); - if (watchdog_enabled_setting == -1) { use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); @@ -3352,10 +3388,19 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["MainloopThreadID"] = (S32)thread_id; #endif +#ifndef LL_BUGSPLAT + // "CrashNotHandled" is set here, while things are running well, + // in case of a freeze. If there is a freeze, the crash logger will be launched + // and can read this value from the debug_info.log. + // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, + // then the value of "CrashNotHandled" will be set to true. + gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; +#else // LL_BUGSPLAT // "CrashNotHandled" is obsolete; it used (not very successsfully) // to try to distinguish crashes from freezes gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); +#endif // ! LL_BUGSPLAT // Insert crash host url (url to post crash log to) if configured. This insures // that the crash report will go to the proper location in the case of a -- cgit v1.2.3 From e86c0b3d0fbc5f91090241be959ef19bfffd8636 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 5 Mar 2019 04:44:29 -0500 Subject: fix error message reporting? --- indra/newview/llappviewer.cpp | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f9ee22d20a..8b9f9085b1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -751,16 +751,7 @@ public: } }; -namespace { -// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide -// this little helper function. -void fast_exit(int rc) -{ - _exit(rc); -} - - -} +static S32 sQAModeTermCode = 0; // set from QAModeTermCode to specify exit code for LL_ERRS bool LLAppViewer::init() { @@ -800,17 +791,8 @@ bool LLAppViewer::init() initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); - // Although initLoggingAndGetLastDuration() is the right place to mess with - // overrideCrashOnError(), we can't query gSavedSettings until after - // initConfiguration(). - S32 rc(gSavedSettings.getS32("QAModeTermCode")); - if (rc >= 0) - { - // QAModeTermCode set, terminate with that rc on LL_ERRS. Use - // fast_exit() rather than exit() because normal cleanup depends too - // much on successful startup! - LLError::overrideCrashOnError(boost::bind(fast_exit, rc)); - } + // if a return code is set for error exit, save it here for use in fatalErrorHandler + sQAModeTermCode = gSavedSettings.getS32("QAModeTermCode"); mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); @@ -2152,8 +2134,7 @@ bool LLAppViewer::initThreads() return true; } -#ifndef LL_BUGSPLAT -void errorCallback(const std::string &error_string) +LLError::ErrCrashHandlerResult fatalErrorHandler(const std::string &error_string) { #ifndef LL_RELEASE_FOR_DOWNLOAD OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); @@ -2167,8 +2148,15 @@ void errorCallback(const std::string &error_string) // haven't actually trashed anything yet, we can afford to write the whole // static info file. LLAppViewer::instance()->writeDebugInfo(); + + if (sQAModeTermCode) + { + _exit(sQAModeTermCode); + return LLError::ERR_DO_NOT_CRASH; // notreached + } + + return LLError::ERR_CRASH; } -#endif // ! LL_BUGSPLAT void LLAppViewer::initLoggingAndGetLastDuration() { @@ -2178,6 +2166,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "") ); + LLError::setFatalHandler(fatalErrorHandler); // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, @@ -3728,12 +3717,8 @@ void LLAppViewer::processMarkerFiles() else if (marker_is_same_version) { // the file existed, is ours, and matched our version, so we can report on what it says - LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL; -# if LL_BUGSPLAT + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL; gLastExecEvent = LAST_EXEC_OTHER_CRASH; -# else - gLastExecEvent = LAST_EXEC_FROZE; -# endif } else { -- cgit v1.2.3 From 07870a9ebb17e7a31df276f4ac2d8f52fec2a3b0 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 5 Mar 2019 13:57:02 -0500 Subject: rename crash handler to hook, and make them chainable by putting back the get and documenting it --- indra/newview/llappviewer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8b9f9085b1..8616fe7c76 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2134,7 +2134,7 @@ bool LLAppViewer::initThreads() return true; } -LLError::ErrCrashHandlerResult fatalErrorHandler(const std::string &error_string) +LLError::ErrFatalHookResult fatalErrorHook(const std::string &error_string) { #ifndef LL_RELEASE_FOR_DOWNLOAD OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); @@ -2166,7 +2166,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "") ); - LLError::setFatalHandler(fatalErrorHandler); + LLError::setFatalHook(fatalErrorHook); // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, -- cgit v1.2.3 From 1e98a607d08019f66ae878e4cb247e850a7443cf Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 4 Jun 2019 10:06:43 -0400 Subject: try putting fatal message into dynamic crash data --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8616fe7c76..0e97ed5a47 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3388,7 +3388,7 @@ void LLAppViewer::writeSystemInfo() // "CrashNotHandled" is obsolete; it used (not very successsfully) // to try to distinguish crashes from freezes gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; - gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); + gDebugInfo["Dynamic"]["FatalMessage"] = LLError::getFatalMessage(); #endif // ! LL_BUGSPLAT // Insert crash host url (url to post crash log to) if configured. This insures -- cgit v1.2.3 From e711376cc75a51973291d1730467c0b6e3a74226 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 5 Jun 2019 14:27:48 -0400 Subject: assorted cleanup --- indra/newview/llappviewer.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0e97ed5a47..35f9d7f4fd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3386,9 +3386,8 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; #else // LL_BUGSPLAT // "CrashNotHandled" is obsolete; it used (not very successsfully) - // to try to distinguish crashes from freezes + // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; - gDebugInfo["Dynamic"]["FatalMessage"] = LLError::getFatalMessage(); #endif // ! LL_BUGSPLAT // Insert crash host url (url to post crash log to) if configured. This insures @@ -3617,7 +3616,7 @@ void LLAppViewer::handleViewerCrash() if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]); - gDebugInfo["Dynamic"]["FatalMessage"] = LLError::getFatalMessage(); + gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); // Close the debug file pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead. @@ -5476,11 +5475,6 @@ void LLAppViewer::pauseMainloopTimeout() void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) { -// if(!restoreErrorTrap()) -// { -// LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL; -// } - if(mMainloopTimeout) { if(secs < 0.0f) -- cgit v1.2.3 From d0619f8e476c1c5118ae926dfe1746f1dda986d8 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 24 Sep 2019 14:27:21 -0400 Subject: improve fatal hook logging --- indra/newview/llappviewer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 35f9d7f4fd..9258d1a219 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2166,7 +2166,8 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "") ); - LLError::setFatalHook(fatalErrorHook); + + // TBD fatal hook belongs here // Remove the last ".old" log file. std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, @@ -2228,6 +2229,10 @@ void LLAppViewer::initLoggingAndGetLastDuration() { LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; } + + // TBD - temporary location for fatal hook (should be above, but for now it logs...) + LLError::setFatalHook(fatalErrorHook); + } bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, -- cgit v1.2.3 From a45ca18ff8160bc3edc584d6516ca019dd6c6275 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 25 Sep 2019 12:59:20 -0400 Subject: when using bugsplat, do not catch SIGABRT; also, fix signal setting in Mac (broken macro) --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9258d1a219..8009a9c117 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2231,8 +2231,8 @@ void LLAppViewer::initLoggingAndGetLastDuration() } // TBD - temporary location for fatal hook (should be above, but for now it logs...) + LL_DEBUGS("FatalHook") << "initial setting of default fatalhook" << LL_ENDL; LLError::setFatalHook(fatalErrorHook); - } bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, -- cgit v1.2.3 From 88746478583711951d04a3ea709ccf1667ddf535 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 3 Mar 2021 19:33:02 +0200 Subject: SL-14940 Fixed ignoring custom cache path fix by Ansariel (https://vcs.firestormviewer.org/phoenix-firestorm/changeset/dace23b988af90a65ef57b0b9f540fc48d439dc3) --- indra/newview/llappviewer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ea0b950e62..0dc2c7d326 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4132,8 +4132,6 @@ bool LLAppViewer::initCache() const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100; const unsigned int disk_cache_bytes = disk_cache_mb * 1024 * 1024; const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); - const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); bool texture_cache_mismatch = false; if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) @@ -4181,6 +4179,9 @@ bool LLAppViewer::initCache() gSavedSettings.setString("CacheLocationTopFolder", ""); } + const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); + if (!read_only) { if (mPurgeCache) -- cgit v1.2.3 From 3067f56b1f1be6506b0bddd2889854ad7fdf4d8a Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 9 Mar 2021 21:57:32 +0200 Subject: Revert "SL-14940 Fixed ignoring custom cache path" This reverts commit 88746478583711951d04a3ea709ccf1667ddf535. --- indra/newview/llappviewer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0dc2c7d326..ea0b950e62 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4132,6 +4132,8 @@ bool LLAppViewer::initCache() const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100; const unsigned int disk_cache_bytes = disk_cache_mb * 1024 * 1024; const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); + const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); bool texture_cache_mismatch = false; if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) @@ -4179,9 +4181,6 @@ bool LLAppViewer::initCache() gSavedSettings.setString("CacheLocationTopFolder", ""); } - const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); - if (!read_only) { if (mPurgeCache) -- cgit v1.2.3 From 4076208a72dbcb36adbdfcca86a9fbcc12d2bda3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 10 Mar 2021 20:28:00 +0200 Subject: SL-14961 Bugsplat logging --- indra/newview/llappviewer.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f518704e06..a1d73acfa5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5549,6 +5549,33 @@ void LLAppViewer::forceErrorDriverCrash() glDeleteTextures(1, NULL); } +void LLAppViewer::forceErrorCoroutineCrash() +{ + LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL; + LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw std::exception("A deliberate crash from LLCoros"); }); +} + +void LLAppViewer::forceErrorThreadCrash() +{ + class LLCrashTestThread : public LLThread + { + public: + + LLCrashTestThread() : LLThread("Crash logging test thread") + { + } + + void run() + { + LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL; + } + }; + + LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL; + LLCrashTestThread *thread = new LLCrashTestThread(); + thread->start(); +} + void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) { if(!mMainloopTimeout) -- cgit v1.2.3 From ed98ebb8115bffc5cf78ec00e33adf2243c55f0d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 12 Mar 2021 18:19:53 +0200 Subject: SL-14961 Coroutine crash was not reported to bugsplat --- indra/newview/llappviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a1d73acfa5..7c2f622abd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5552,7 +5552,7 @@ void LLAppViewer::forceErrorDriverCrash() void LLAppViewer::forceErrorCoroutineCrash() { LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL; - LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw std::exception("A deliberate crash from LLCoros"); }); + LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); }); } void LLAppViewer::forceErrorThreadCrash() -- cgit v1.2.3 From c0f28ae36261cc31d6412c42c05d1b7719a2c04b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 18 Mar 2021 22:45:38 +0200 Subject: SL-14927 Some avatar names not resolving --- indra/newview/llappviewer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7c2f622abd..fe2da2f989 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5226,10 +5226,9 @@ void LLAppViewer::sendLogoutRequest() } } -void LLAppViewer::updateNameLookupUrl() +void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp) { - LLViewerRegion* region = gAgent.getRegion(); - if (!region || !region->capabilitiesReceived()) + if (!regionp || !regionp->capabilitiesReceived()) { return; } @@ -5238,7 +5237,7 @@ void LLAppViewer::updateNameLookupUrl() bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL(); std::string name_lookup_url; name_lookup_url.reserve(128); // avoid a memory allocation below - name_lookup_url = region->getCapability("GetDisplayNames"); + name_lookup_url = regionp->getCapability("GetDisplayNames"); bool have_capability = !name_lookup_url.empty(); if (have_capability) { -- cgit v1.2.3 From c9fc4349b7d4ab1f5a7bfc0125014a96a07e51a3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 11 May 2021 21:42:14 -0400 Subject: SL-10297: Move LL_ERRS crash location into the LL_ERRS macro itself. Introduce Oz's LLERROR_CRASH macro analogous to the old LLError::crashAndLoop() function. Change LL_ENDL macro so that, after calling flush(), if the CallSite is for LEVEL_ERROR, we invoke LLERROR_CRASH right there. Change the meaning of LLError::FatalFunction. It used to be responsible for the actual crash (hence crashAndLoop()). Now, instead, its role is to disrupt control flow in some other way if you DON'T want to crash: throw an exception, or call exit() or some such. Any FatalFunction that returns normally will fall into the new crash in LL_ENDL. Accordingly, the new default FatalFunction is a no-op lambda. This eliminates the need to test for empty (not set) FatalFunction in Log::flush(). Remove LLError::crashAndLoop() because the official LL_ERRS crash is now in LL_ENDL. One of the two common use cases for setFatalFunction() used to be to intercept control in the last moments before crashing -- not to crash or to avoid crashing, but to capture the LL_ERRS message in some way. Especially when that's temporary, though (e.g. LLLeap), saving and restoring the previous FatalFunction only works when the lifespans of the relevant objects are strictly LIFO. Either way, that's a misuse of FatalFunction. Fortunately the Recorder mechanism exactly addresses that case. Introduce a GenericRecorder template subclass, with LLError::addGenericRecorder(callable) that accepts a callable with suitable (level, message) signature, instantiates a GenericRecorder, adds it to the logging machinery and returns the RecorderPtr for possible later use with removeRecorder(). Change llappviewer.cpp's errorCallback() to an addGenericRecorder() callable. Its role was simply to update gDebugInfo["FatalMessage"] with the LL_ERRS message, then call writeDebugInfo(), before calling crashAndLoop() to finish crashing. Remove the crashAndLoop() call, retaining the gDebugInfo logic. Pass errorCallback() to LLError::addGenericRecorder() instead of setFatalFunction(). Oddly, errorCallback()'s crashAndLoop() call was conditional on a compile-time SHADER_CRASH_NONFATAL symbol. The new mechanism provides no way to support SHADER_CRASH_NONFATAL -- it is a Bad Idea to return normally from any LL_ERRS invocation! Rename LLLeapImpl::fatalFunction() to onError(). Instead of passing it to LLError::setFatalFunction(), pass it to addGenericRecorder(). Capture the returned RecorderPtr in mRecorder, replacing mPrevFatalFunction. Then ~LLLeapImpl() calls removeRecorder(mRecorder) instead of restoring mPrevFatalFunction (which, as noted above, was order-sensitive). Of course, every enabled Recorder is called with every log message. onError() and errorCallback() must specifically test for calls with LEVEL_ERROR. LLSingletonBase::logerrs() used to call LLError::getFatalFunction(), check the return and call it if non-empty, else call LLError::crashAndLoop(). Replace all that with LLERROR_CRASH. Remove from llappviewer.cpp the watchdog_llerrs_callback() and watchdog_killer_callback() functions. watchdog_killer_callback(), passed to Watchdog::init(), used to setFatalFunction(watchdog_llerrs_callback) and then invoke LL_ERRS() -- which seems a bit roundabout. watchdog_llerrs_callback(), in turn, replicated much of the logic in the primary errorCallback() function before replicating the crash from llwatchdog.cpp's default_killer_callback(). Instead, pass LLWatchdog::init() a lambda that invokes the LL_ERRS() message formerly found in watchdog_killer_callback(). It no longer needs to override FatalFunction with watchdog_llerrs_callback() because errorCallback() will still be called as a Recorder, obviating watchdog_llerrs_callback()'s first half; and LL_ENDL will handle the crash, obviating the second half. Remove from llappviewer.cpp the static fast_exit() function, which was simply an alias for _exit() acceptable to boost::bind(). Use a lambda directly calling _exit() instead of using boost::bind() at all. In the CaptureLog class in llcommon/tests/wrapllerrs.h, instead of statically referencing the wouldHaveCrashed() function from test.cpp, simply save and restore the current FatalFunction across the LLError::saveAndResetSettings() call. llerror_test.cpp calls setFatalFunction(fatalCall), where fatalCall() was a function that simply set a fatalWasCalled bool rather than actually crashing in any way. Of course, that implementation would now lead to crashing the test program. Make fatalCall() throw a new FatalWasCalled exception. Introduce a CATCH(LL_ERRS("tag"), "message") macro that expands to: LL_ERRS("tag") << "message" << LL_ENDL; within a try/catch block that catches FatalWasCalled and sets the same bool. Change all existing LL_ERRS() in llerror_test.cpp to corresponding CATCH() calls. In fact there's also an LL_DEBUGS(bad tag) invocation that exercises an LL_ERRS internal to llerror.cpp; wrap that too. --- indra/newview/llappviewer.cpp | 67 +++++++++++-------------------------------- 1 file changed, 17 insertions(+), 50 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0b2cdff36c..b03e821d32 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -760,17 +760,6 @@ public: } }; -namespace { -// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide -// this little helper function. -void fast_exit(int rc) -{ - _exit(rc); -} - - -} - bool LLAppViewer::init() { @@ -822,9 +811,9 @@ bool LLAppViewer::init() if (rc >= 0) { // QAModeTermCode set, terminate with that rc on LL_ERRS. Use - // fast_exit() rather than exit() because normal cleanup depends too + // _exit() rather than exit() because normal cleanup depends too // much on successful startup! - LLError::setFatalFunction(boost::bind(fast_exit, rc)); + LLError::setFatalFunction([rc](const std::string&){ _exit(rc); }); } mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); @@ -2185,28 +2174,6 @@ bool LLAppViewer::cleanup() return true; } -// A callback for LL_ERRS() to call during the watchdog error. -void watchdog_llerrs_callback(const std::string &error_string) -{ - gLLErrorActivated = true; - - gDebugInfo["FatalMessage"] = error_string; - LLAppViewer::instance()->writeDebugInfo(); - -#ifdef LL_WINDOWS - RaiseException(0,0,0,0); -#else - raise(SIGQUIT); -#endif -} - -// A callback for the watchdog to call. -void watchdog_killer_callback() -{ - LLError::setFatalFunction(watchdog_llerrs_callback); - LL_ERRS() << "Watchdog killer event" << LL_ENDL; -} - bool LLAppViewer::initThreads() { static const bool enable_threads = true; @@ -2241,24 +2208,23 @@ bool LLAppViewer::initThreads() return true; } -void errorCallback(const std::string &error_string) +void errorCallback(LLError::ELevel level, const std::string &error_string) { + if (level == LLError::LEVEL_ERROR) + { #ifndef LL_RELEASE_FOR_DOWNLOAD - OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); + OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); #endif - //Set the ErrorActivated global so we know to create a marker file - gLLErrorActivated = true; - - gDebugInfo["FatalMessage"] = error_string; - // We're not already crashing -- we simply *intend* to crash. Since we - // haven't actually trashed anything yet, we can afford to write the whole - // static info file. - LLAppViewer::instance()->writeDebugInfo(); + //Set the ErrorActivated global so we know to create a marker file + gLLErrorActivated = true; -#ifndef SHADER_CRASH_NONFATAL - LLError::crashAndLoop(error_string); -#endif + gDebugInfo["FatalMessage"] = error_string; + // We're not already crashing -- we simply *intend* to crash. Since we + // haven't actually trashed anything yet, we can afford to write the whole + // static info file. + LLAppViewer::instance()->writeDebugInfo(); + } } void LLAppViewer::initLoggingAndGetLastDuration() @@ -2269,7 +2235,7 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "") ); - LLError::setFatalFunction(errorCallback); + LLError::addGenericRecorder(&errorCallback); //LLError::setTimeFunction(getRuntime); // Remove the last ".old" log file. @@ -3030,7 +2996,8 @@ bool LLAppViewer::initWindow() if (use_watchdog) { - LLWatchdog::getInstance()->init(watchdog_killer_callback); + LLWatchdog::getInstance()->init( + [](){ LL_ERRS() << "Watchdog killer event" << LL_ENDL; }); } LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL; -- cgit v1.2.3 From 28862ab53b9e532bf6ff789743d80b33af10f395 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 12 May 2021 14:21:27 -0400 Subject: SL-10297: Clean up a few merge glitches. --- indra/newview/llappviewer.cpp | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c44690ac25..7d7d41fe22 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2298,10 +2298,6 @@ void LLAppViewer::initLoggingAndGetLastDuration() { LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; } - - // TBD - temporary location for fatal hook (should be above, but for now it logs...) - LL_DEBUGS("FatalHook") << "initial setting of default fatalhook" << LL_ENDL; - LLError::setFatalHook(fatalErrorHook); } bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, @@ -2998,16 +2994,15 @@ bool LLAppViewer::initWindow() use_watchdog = bool(watchdog_enabled_setting); } - LL_INFOS("AppInit") << "watchdog" - << (use_watchdog ? " " : " NOT ") - << "enabled" - << " (setting = " << watchdog_enabled_setting << ")" - << LL_ENDL; + LL_INFOS("AppInit") << "watchdog" + << (use_watchdog ? " " : " NOT ") + << "enabled" + << " (setting = " << watchdog_enabled_setting << ")" + << LL_ENDL; if (use_watchdog) { - LLWatchdog::getInstance()->init( - [](){ LL_ERRS() << "Watchdog killer event" << LL_ENDL; }); + LLWatchdog::getInstance()->init(); } LLNotificationsUI::LLNotificationManager::getInstance(); @@ -3441,8 +3436,8 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); - gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value()); - gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits()); + gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value()); + gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits()); gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple(); // The user is not logged on yet, but record the current grid choice login url @@ -3461,11 +3456,11 @@ void LLAppViewer::writeSystemInfo() // and can read this value from the debug_info.log. // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, // then the value of "CrashNotHandled" will be set to true. - gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; + gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true); #else // LL_BUGSPLAT // "CrashNotHandled" is obsolete; it used (not very successsfully) // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze - gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; + gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false); #endif // ! LL_BUGSPLAT // Insert crash host url (url to post crash log to) if configured. This insures @@ -3497,7 +3492,7 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); - gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); + gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin()); gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); @@ -3627,7 +3622,7 @@ void LLAppViewer::handleViewerCrash() // The crash is being handled here so set this value to false. // Otherwise the crash logger will think this crash was a freeze. - gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; + gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false); //Write out the crash status file //Use marker file style setup, as that's the simplest, especially since -- cgit v1.2.3