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/llcommon/llerror.cpp | 51 ++++++-------------- indra/llcommon/llerror.h | 24 ++++++++-- indra/llcommon/llerrorcontrol.h | 36 ++------------ indra/llcommon/llleap.cpp | 12 ++--- indra/llcommon/llsingleton.cpp | 10 +--- indra/llcommon/tests/llerror_test.cpp | 2 +- indra/llcommon/tests/wrapllerrs.h | 10 ++-- indra/newview/llappviewer.cpp | 89 ++++++----------------------------- indra/newview/llwatchdog.cpp | 18 ++----- indra/newview/llwatchdog.h | 6 +-- indra/test/test.cpp | 6 +-- 11 files changed, 70 insertions(+), 194 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 335a0995fe..0ddce353f1 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -683,7 +683,6 @@ namespace LLError::setDefaultLevel(LLError::LEVEL_INFO); LLError::setAlwaysFlush(true); LLError::setEnabledLogTypesMask(0xFFFFFFFF); - LLError::setFatalFunction(LLError::crashAndLoop); LLError::setTimeFunction(LLError::utcTime); // log_to_stderr is only false in the unit and integration tests to keep builds quieter @@ -719,16 +718,16 @@ namespace LLError commonInit(user_dir, app_dir, log_to_stderr); } - void setFatalFunction(const FatalFunction& f) + void overrideCrashOnError(const FatalFunction& fatal_function) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - s->mCrashFunction = f; + s->mCrashFunction = fatal_function; } - FatalFunction getFatalFunction() + void restoreCrashOnError() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - return s->mCrashFunction; + s->mCrashFunction = NULL; } std::string getFatalMessage() @@ -1306,12 +1305,12 @@ namespace LLError return ; } - void Log::flush(std::ostringstream* out, const CallSite& site) + bool Log::flush(std::ostringstream* out, const CallSite& site) { LLMutexTrylock lock(&gLogMutex,5); if (!lock.isLocked()) { - return; + return true; } // If we hit a logging request very late during shutdown processing, @@ -1319,7 +1318,7 @@ namespace LLError // DO NOT resurrect them. if (Settings::wasDeleted() || Globals::wasDeleted()) { - return; + return true; } Globals* g = Globals::getInstance(); @@ -1353,7 +1352,7 @@ namespace LLError } else { - return; + return true; } } else @@ -1370,11 +1369,14 @@ namespace LLError if (site.mLevel == LEVEL_ERROR) { g->mFatalMessage = message; - if (s->mCrashFunction) - { - s->mCrashFunction(message); - } + if (s->mCrashFunction) + { + s->mCrashFunction(message); + return false; + } } + + return true; } } @@ -1437,29 +1439,6 @@ namespace LLError return s->mShouldLogCallCounter; } -#if LL_WINDOWS - // VC80 was optimizing the error away. - #pragma optimize("", off) -#endif - void crashAndLoop(const std::string& message) - { - // Now, we go kaboom! - int* make_me_crash = NULL; - - *make_me_crash = 0; - - while(true) - { - // Loop forever, in case the crash didn't work? - } - - // this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever. - exit(EXIT_FAILURE); - } -#if LL_WINDOWS - #pragma optimize("", on) -#endif - std::string utcTime() { time_t now = time(NULL); diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 0a78229555..cbade88f61 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -199,8 +199,12 @@ namespace LLError public: static bool shouldLog(CallSite&); static std::ostringstream* out(); + static void flush(std::ostringstream* out, char* message); - static void flush(std::ostringstream*, const CallSite&); + + // returns false iff there is a fatal crash override in effect + static bool flush(std::ostringstream*, const CallSite&); + static std::string demangle(const char* mangled); }; @@ -367,10 +371,20 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; #define LL_NEWLINE '\n' -#define LL_ENDL \ - LLError::End(); \ - LLError::Log::flush(_out, _site); \ - } \ +// Use this only in LL_ERRS or in a place that LL_ERRS may not be used +#define LLERROR_CRASH \ +{ \ + int* make_me_crash = NULL;\ + *make_me_crash = 0; \ + exit(*make_me_crash); \ +} + +#define LL_ENDL \ + LLError::End(); \ + if (LLError::Log::flush(_out, _site) \ + && _site.mLevel == LLError::LEVEL_ERROR) \ + LLERROR_CRASH \ + } \ } while(0) // NEW Macros for debugging, allow the passing of a string tag diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 276d22fc36..7ca6ddb737 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -92,41 +92,13 @@ namespace LLError /* Control functions. */ - typedef boost::function FatalFunction; - LL_COMMON_API void crashAndLoop(const std::string& message); - // Default fatal function: access null pointer and loops forever - - LL_COMMON_API void setFatalFunction(const FatalFunction&); - // The fatal function will be called when an message of LEVEL_ERROR - // is logged. Note: supressing a LEVEL_ERROR message from being logged - // (by, for example, setting a class level to LEVEL_NONE), will keep - // the that message from causing the fatal funciton to be invoked. - - LL_COMMON_API FatalFunction getFatalFunction(); - // Retrieve the previously-set FatalFunction + LL_COMMON_API void overrideCrashOnError(const FatalFunction&); + LL_COMMON_API void restoreCrashOnError(); + LL_COMMON_API std::string getFatalMessage(); - // Retrieve the message last passed to FatalFunction, if any - - /// temporarily override the FatalFunction for the duration of a - /// particular scope, e.g. for unit tests - class LL_COMMON_API OverrideFatalFunction - { - public: - OverrideFatalFunction(const FatalFunction& func): - mPrev(getFatalFunction()) - { - setFatalFunction(func); - } - ~OverrideFatalFunction() - { - setFatalFunction(mPrev); - } - - private: - FatalFunction mPrev; - }; + // Retrieve the message last passed to LL_ERRS, if any typedef std::string (*TimeFunction)(); LL_COMMON_API std::string utcTime(); diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index cf8f8cc6a5..f7bfa36bb5 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -59,7 +59,6 @@ public: // pump name -- so it should NOT need tweaking for uniqueness. mReplyPump(LLUUID::generateNewID().asString()), mExpect(0), - mPrevFatalFunction(LLError::getFatalFunction()), // Instantiate a distinct LLLeapListener for this plugin. (Every // plugin will want its own collection of managed listeners, etc.) // Pass it a callback to our connect() method, so it can send events @@ -146,7 +145,7 @@ public: .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1)); // For our lifespan, intercept any LL_ERRS so we can notify plugin - LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1)); + LLError::overrideCrashOnError(boost::bind(&LLLeapImpl::fatalFunction, this, _1)); // Send child a preliminary event reporting our own reply-pump name -- // which would otherwise be pretty tricky to guess! @@ -162,8 +161,8 @@ public: virtual ~LLLeapImpl() { LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL; - // Restore original FatalFunction - LLError::setFatalFunction(mPrevFatalFunction); + // Restore original fatal crash behavior for LL_ERRS + LLError::restoreCrashOnError(); } // Listener for failed launch attempt @@ -397,8 +396,8 @@ public: mainloop.post(nop); } - // forward the call to the previous FatalFunction - mPrevFatalFunction(error); + // go ahead and do the crash that LLError would have done + LLERROR_CRASH } private: @@ -421,7 +420,6 @@ private: mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection; boost::scoped_ptr mBlocker; LLProcess::ReadPipe::size_type mExpect; - LLError::FatalFunction mPrevFatalFunction; boost::scoped_ptr mListener; }; diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index c45c144570..6f254ef670 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -461,15 +461,7 @@ void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, co // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) std::ostringstream out; out << p1 << p2 << p3 << p4; - auto crash = LLError::getFatalFunction(); - if (crash) - { - crash(out.str()); - } - else - { - LLError::crashAndLoop(out.str()); - } + LLERROR_CRASH; } std::string LLSingletonBase::demangle(const char* mangled) diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 8e1f4c14ac..2f8923d2de 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -120,7 +120,7 @@ namespace tut mPriorErrorSettings = LLError::saveAndResetSettings(); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); - LLError::setFatalFunction(fatalCall); + LLError::overrideCrashOnError(fatalCall); LLError::addRecorder(mRecorder); } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index b07d5afbd8..b280271476 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -54,17 +54,15 @@ struct WrapLLErrs // Resetting Settings discards the default Recorder that writes to // stderr. Otherwise, expected llerrs (LL_ERRS) messages clutter the // console output of successful tests, potentially confusing things. - mPriorErrorSettings(LLError::saveAndResetSettings()), - // Save shutdown function called by LL_ERRS - mPriorFatal(LLError::getFatalFunction()) + mPriorErrorSettings(LLError::saveAndResetSettings()) { // Make LL_ERRS call our own operator() method - LLError::setFatalFunction(boost::bind(&WrapLLErrs::operator(), this, _1)); + LLError::overrideCrashOnError(boost::bind(&WrapLLErrs::operator(), this, _1)); } ~WrapLLErrs() { - LLError::setFatalFunction(mPriorFatal); + LLError::restoreCrashOnError(); LLError::restoreSettings(mPriorErrorSettings); } @@ -203,7 +201,7 @@ public: mOldSettings(LLError::saveAndResetSettings()), mRecorder(new CaptureLogRecorder()) { - LLError::setFatalFunction(wouldHaveCrashed); + LLError::overrideCrashOnError(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } 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. } diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index dd6c77ca7d..2f3e5db84f 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -31,15 +31,6 @@ const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000; -void default_killer_callback() -{ -#ifdef LL_WINDOWS - RaiseException(0,0,0,0); -#else - raise(SIGQUIT); -#endif -} - // This class runs the watchdog timing thread. class LLWatchdogTimerThread : public LLThread { @@ -157,8 +148,7 @@ void LLWatchdogTimeout::ping(const std::string& state) LLWatchdog::LLWatchdog() : mSuspectsAccessMutex(), mTimer(NULL), - mLastClockCount(0), - mKillerCallback(&default_killer_callback) + mLastClockCount(0) { } @@ -180,9 +170,8 @@ void LLWatchdog::remove(LLWatchdogEntry* e) unlockThread(); } -void LLWatchdog::init(killer_event_callback func) +void LLWatchdog::init() { - mKillerCallback = func; if(!mSuspectsAccessMutex && !mTimer) { mSuspectsAccessMutex = new LLMutex(); @@ -249,8 +238,7 @@ void LLWatchdog::run() mTimer->stop(); } - LL_INFOS() << "Watchdog detected error:" << LL_ENDL; - mKillerCallback(); + LL_ERRS() << "Watchdog timer expired; assuming viewer is hung and crashing" << LL_ENDL; } } diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index 9a6624258e..ce5cf748f4 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -83,9 +83,7 @@ public: void add(LLWatchdogEntry* e); void remove(LLWatchdogEntry* e); - typedef boost::function killer_event_callback; - - void init(killer_event_callback func = NULL); + void init(); void run(); void cleanup(); @@ -98,8 +96,6 @@ private: LLMutex* mSuspectsAccessMutex; LLWatchdogTimerThread* mTimer; U64 mLastClockCount; - - killer_event_callback mKillerCallback; }; #endif // LL_LLTHREADWATCHDOG_H diff --git a/indra/test/test.cpp b/indra/test/test.cpp index b14c2eb255..125de72b79 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -146,7 +146,7 @@ public: mOldSettings(LLError::saveAndResetSettings()), mRecorder(new RecordToTempFile(pool)) { - LLError::setFatalFunction(wouldHaveCrashed); + LLError::overrideCrashOnError(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } @@ -508,7 +508,7 @@ void stream_groups(std::ostream& s, const char* app) void wouldHaveCrashed(const std::string& message) { - tut::fail("llerrs message: " + message); + tut::fail("fatal error message: " + message); } static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL; @@ -532,7 +532,7 @@ int main(int argc, char **argv) LLError::initForApplication(".", ".", false /* do not log to stderr */); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); } - LLError::setFatalFunction(wouldHaveCrashed); + LLError::overrideCrashOnError(wouldHaveCrashed); std::string test_app_name(argv[0]); std::string test_log = test_app_name + ".log"; LLFile::remove(test_log); -- 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') 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/CMakeLists.txt | 10 +++++++ indra/cmake/Copy3rdPartyLibs.cmake | 4 +-- indra/cmake/LLAddBuildTest.cmake | 13 ++++++++- indra/cmake/Variables.cmake | 1 - indra/cmake/bugsplat.cmake | 53 +++++++++++++++++++--------------- indra/llcommon/CMakeLists.txt | 9 +++--- indra/llcommon/llerror.cpp | 21 +++++++++----- indra/llcommon/llerror.h | 20 +++++++------ indra/llcommon/llerrorcontrol.h | 14 +++++++-- indra/llcommon/llleap.cpp | 30 +------------------ indra/llcommon/tests/wrapllerrs.h | 5 ++-- indra/llcorehttp/CMakeLists.txt | 1 + indra/llimage/CMakeLists.txt | 1 + indra/llmath/CMakeLists.txt | 1 + indra/newview/CMakeLists.txt | 36 +++++++++++------------ indra/newview/llappviewer.cpp | 59 +++++++++++++++++++++++++++++++++----- indra/newview/llwatchdog.cpp | 8 +++--- indra/test/CMakeLists.txt | 6 +++- indra/test/test.cpp | 10 +++---- 19 files changed, 185 insertions(+), 117 deletions(-) (limited to 'indra') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 62a8f3f003..cf6029c4ae 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -13,6 +13,7 @@ project(${ROOT_PROJECT_NAME}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(Variables) +include(bugsplat) include(BuildVersion) if (NOT CMAKE_BUILD_TYPE) @@ -89,6 +90,15 @@ set_property( PROPERTY VS_STARTUP_PROJECT secondlife-bin ) +if (USE_BUGSPLAT) + if (BUGSPLAT_DB) + message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'") + else (BUGSPLAT_DB) + message(WARNING "Building with BugSplat, but no database name set (BUGSPLAT_DB)") + endif (BUGSPLAT_DB) +else (USE_BUGSPLAT) + message(STATUS "Not building with BugSplat") +endif (USE_BUGSPLAT) if (LL_TESTS) # Define after the custom targets are created so # individual apps can add themselves as dependencies diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c73a1fdb47..ebb6379aed 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -50,7 +50,7 @@ if(WINDOWS) # Filenames are different for 32/64 bit BugSplat file and we don't # have any control over them so need to branch. - if (BUGSPLAT_DB) + if (USE_BUGSPLAT) if(ADDRESS_SIZE EQUAL 32) set(release_files ${release_files} BugSplat.dll) set(release_files ${release_files} BugSplatRc.dll) @@ -60,7 +60,7 @@ if(WINDOWS) set(release_files ${release_files} BugSplatRc64.dll) set(release_files ${release_files} BsSndRpt64.exe) endif(ADDRESS_SIZE EQUAL 32) - endif (BUGSPLAT_DB) + endif (USE_BUGSPLAT) if (FMODEX) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index b3f42c1a5e..fa10a9d443 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -2,6 +2,7 @@ include(00-Common) include(LLTestCommand) include(GoogleMock) +include(bugsplat) include(Tut) #***************************************************************************** @@ -22,7 +23,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) # there is another branch that will conflict heavily with any changes here. INCLUDE(GoogleMock) - IF(LL_TEST_VERBOSE) MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") ENDIF(LL_TEST_VERBOSE) @@ -87,6 +87,12 @@ INCLUDE(GoogleMock) IF(LL_TEST_VERBOSE) MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") ENDIF(LL_TEST_VERBOSE) + + if (USE_BUGSPLAT) + SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES} + APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") + endif (USE_BUGSPLAT) + # Headers GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES) SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) @@ -223,6 +229,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}") endif(USESYSTEMLIBS) + if (USE_BUGSPLAT) + SET_PROPERTY(SOURCE ${source_files} + APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") + endif (USE_BUGSPLAT) + # The following was copied to llcorehttp/CMakeLists.txt's texture_load target. # Any changes made here should be replicated there. if (WINDOWS) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index a5770c5528..c81b22e572 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -34,7 +34,6 @@ set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable fo set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)") set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism") set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files") -set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired") if(LIBS_CLOSED_DIR) file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR) diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 59644b73ce..749ea05403 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -1,25 +1,32 @@ -# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database -# name. -if (BUGSPLAT_DB) - if (USESYSTEMLIBS) - message(STATUS "Looking for system BugSplat") - set(BUGSPLAT_FIND_QUIETLY ON) - set(BUGSPLAT_FIND_REQUIRED ON) - include(FindBUGSPLAT) - else (USESYSTEMLIBS) - message(STATUS "Engaging autobuild BugSplat") - include(Prebuilt) - use_prebuilt_binary(bugsplat) - if (WINDOWS) - set(BUGSPLAT_LIBRARIES - ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib - ) - elseif (DARWIN) - find_library(BUGSPLAT_LIBRARIES BugsplatMac - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") - else (WINDOWS) +if (INSTALL_PROPRIETARY) + set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system") +else (INSTALL_PROPRIETARY) + set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") +endif (INSTALL_PROPRIETARY) + +if (USE_BUGSPLAT) + if (NOT USESYSTEMLIBS) + include(Prebuilt) + use_prebuilt_binary(bugsplat) + if (WINDOWS) + set(BUGSPLAT_LIBRARIES + ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib + ) + elseif (DARWIN) + find_library(BUGSPLAT_LIBRARIES BugsplatMac + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") + else (WINDOWS) + message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF") + endif (WINDOWS) + else (NOT USESYSTEMLIBS) + set(BUGSPLAT_FIND_QUIETLY ON) + set(BUGSPLAT_FIND_REQUIRED ON) + include(FindBUGSPLAT) + endif (NOT USESYSTEMLIBS) + + set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") - endif (WINDOWS) set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) - endif (USESYSTEMLIBS) -endif (BUGSPLAT_DB) + set(BUGSPLAT_DEFINE "LL_BUGSPLAT") +endif (USE_BUGSPLAT) + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index af41b9e460..e3afa5eca4 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -5,6 +5,7 @@ project(llcommon) include(00-Common) include(LLCommon) +include(bugsplat) include(Linking) include(Boost) include(LLSharedLibs) @@ -257,10 +258,10 @@ set(llcommon_HEADER_FILES set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -if (BUGSPLAT_DB) - set_source_files_properties(llapp.cpp - PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (BUGSPLAT_DB) +if (USE_BUGSPLAT) + set_source_files_properties(${llcommon_SOURCE_FILES} + PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +endif (USE_BUGSPLAT) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 0ddce353f1..77d7fe1b24 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -25,6 +25,7 @@ * $/LicenseInfo$ */ +#define _LLERROR_CPP_ #include "linden_common.h" #include "llerror.h" @@ -724,7 +725,7 @@ namespace LLError s->mCrashFunction = fatal_function; } - void restoreCrashOnError() + void restoreCrashOnError() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); s->mCrashFunction = NULL; @@ -1310,7 +1311,7 @@ namespace LLError LLMutexTrylock lock(&gLogMutex,5); if (!lock.isLocked()) { - return true; + return false; // because this wasn't logged, it cannot be fatal } // If we hit a logging request very late during shutdown processing, @@ -1318,7 +1319,7 @@ namespace LLError // DO NOT resurrect them. if (Settings::wasDeleted() || Globals::wasDeleted()) { - return true; + return false; // because this wasn't logged, it cannot be fatal } Globals* g = Globals::getInstance(); @@ -1352,7 +1353,7 @@ namespace LLError } else { - return true; + return false; // because this wasn't logged, it cannot be fatal } } else @@ -1372,11 +1373,17 @@ namespace LLError if (s->mCrashFunction) { s->mCrashFunction(message); - return false; + return false; // because an override is in effect + } + else + { + return true; // calling macro should crash } } - - return true; + else + { + return false; // not ERROR, so do not crash + } } } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index cbade88f61..07aa5c6f8b 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -202,7 +202,7 @@ namespace LLError static void flush(std::ostringstream* out, char* message); - // returns false iff there is a fatal crash override in effect + // returns false iff the calling macro should crash static bool flush(std::ostringstream*, const CallSite&); static std::string demangle(const char* mangled); @@ -371,18 +371,22 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; #define LL_NEWLINE '\n' +#ifdef _LLERROR_CPP_ +volatile int* gCauseCrash = NULL; +#else +volatile extern int* gCauseCrash; +#endif // _LLERROR_CPP_ + // Use this only in LL_ERRS or in a place that LL_ERRS may not be used -#define LLERROR_CRASH \ -{ \ - int* make_me_crash = NULL;\ - *make_me_crash = 0; \ - exit(*make_me_crash); \ +#define LLERROR_CRASH \ +{ \ + *gCauseCrash = 0; \ + exit(*gCauseCrash); \ } #define LL_ENDL \ LLError::End(); \ - if (LLError::Log::flush(_out, _site) \ - && _site.mLevel == LLError::LEVEL_ERROR) \ + if (LLError::Log::flush(_out, _site)) \ LLERROR_CRASH \ } \ } while(0) diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 7ca6ddb737..af46430f74 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -92,11 +92,19 @@ namespace LLError /* Control functions. */ + typedef boost::function FatalFunction; - LL_COMMON_API void overrideCrashOnError(const FatalFunction&); - LL_COMMON_API void restoreCrashOnError(); - + /// Override the default behavior of crashing on LL_ERRS; this should NEVER be used except in test code + LL_COMMON_API void overrideCrashOnError(const FatalFunction&); + // The fatal function will be called when an message of LEVEL_ERROR + // is logged. Note: supressing a LEVEL_ERROR message from being logged + // (by, for example, setting a class level to LEVEL_NONE), will keep + // the that message from causing the fatal funciton to be invoked. + + /// Undo the effect of the overrideCrashOnError above + LL_COMMON_API void restoreCrashOnError(); + LL_COMMON_API std::string getFatalMessage(); // Retrieve the message last passed to LL_ERRS, if any diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index f7bfa36bb5..bf20c87c89 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -59,6 +59,7 @@ public: // pump name -- so it should NOT need tweaking for uniqueness. mReplyPump(LLUUID::generateNewID().asString()), mExpect(0), + // Instantiate a distinct LLLeapListener for this plugin. (Every // plugin will want its own collection of managed listeners, etc.) // Pass it a callback to our connect() method, so it can send events @@ -144,9 +145,6 @@ public: mStderrConnection = childerr.getPump() .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1)); - // For our lifespan, intercept any LL_ERRS so we can notify plugin - LLError::overrideCrashOnError(boost::bind(&LLLeapImpl::fatalFunction, this, _1)); - // Send child a preliminary event reporting our own reply-pump name -- // which would otherwise be pretty tricky to guess! wstdin(mReplyPump.getName(), @@ -161,8 +159,6 @@ public: virtual ~LLLeapImpl() { LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL; - // Restore original fatal crash behavior for LL_ERRS - LLError::restoreCrashOnError(); } // Listener for failed launch attempt @@ -376,30 +372,6 @@ public: return false; } - void fatalFunction(const std::string& error) - { - // Notify plugin - LLSD event; - event["type"] = "error"; - event["error"] = error; - mReplyPump.post(event); - - // All the above really accomplished was to buffer the serialized - // event in our WritePipe. Have to pump mainloop a couple times to - // really write it out there... but time out in case we can't write. - LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); - LLSD nop; - F64 until = (LLTimer::getElapsedSeconds() + 2).value(); - while (childin.size() && LLTimer::getElapsedSeconds() < until) - { - mainloop.post(nop); - } - - // go ahead and do the crash that LLError would have done - LLERROR_CRASH - } - private: /// We always want to listen on mReplyPump with wstdin(); under some /// circumstances we'll also echo other LLEventPumps to the plugin. diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index b280271476..fedc17dbe9 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -50,11 +50,11 @@ extern void wouldHaveCrashed(const std::string& message); struct WrapLLErrs { - WrapLLErrs(): + WrapLLErrs() // Resetting Settings discards the default Recorder that writes to // stderr. Otherwise, expected llerrs (LL_ERRS) messages clutter the // console output of successful tests, potentially confusing things. - mPriorErrorSettings(LLError::saveAndResetSettings()) + :mPriorErrorSettings(LLError::saveAndResetSettings()) { // Make LL_ERRS call our own operator() method LLError::overrideCrashOnError(boost::bind(&WrapLLErrs::operator(), this, _1)); @@ -210,6 +210,7 @@ public: { LLError::removeRecorder(mRecorder); LLError::restoreSettings(mOldSettings); + LLError::restoreCrashOnError(); } /// Don't assume the message we want is necessarily the LAST log message diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 9dbc6f447e..286c275b90 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -13,6 +13,7 @@ include(LLAddBuildTest) include(LLMessage) include(LLCommon) include(Tut) +include(bugsplat) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 293ada7548..28b8e8c06d 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -11,6 +11,7 @@ include(LLKDU) include(LLImageJ2COJ) include(ZLIB) include(LLAddBuildTest) +include(bugsplat) include(Tut) include_directories( diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 379c3ee9ea..625459823c 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,6 +4,7 @@ project(llmath) include(00-Common) include(LLCommon) +include(bugsplat) include(Boost) include_directories( diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 04f6c9b7f0..bbfa838827 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -8,9 +8,7 @@ include(00-Common) include(Linking) include(Boost) -if (BUGSPLAT_DB) - include(bugsplat) -endif (BUGSPLAT_DB) +include(bugsplat) include(BuildPackagesInfo) include(BuildVersion) include(CMakeCopyIfDifferent) @@ -97,18 +95,18 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) -if (BUGSPLAT_DB) - include_directories( - ${BUGSPLAT_INCLUDE_DIR} - ) -endif (BUGSPLAT_DB) - include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} ${LLXML_SYSTEM_INCLUDE_DIRS} ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS} ) +if (USE_BUGSPLAT) + include_directories(AFTER + ${BUGSPLAT_INCLUDE_DIR} + ) +endif (USE_BUGSPLAT) + set(viewer_SOURCE_FILES groupchatlistener.cpp llaccountingcostmanager.cpp @@ -1390,11 +1388,11 @@ if (DARWIN) ${COREAUDIO_LIBRARY} ) - if (BUGSPLAT_DB) + if (USE_BUGSPLAT) list(APPEND viewer_LIBRARIES ${BUGSPLAT_LIBRARIES} ) - endif (BUGSPLAT_DB) + endif (USE_BUGSPLAT) # Add resource files to the project. set(viewer_RESOURCE_FILES @@ -1729,10 +1727,10 @@ if (SDL_FOUND) ) endif (SDL_FOUND) -if (BUGSPLAT_DB) +if (USE_BUGSPLAT) set_property(TARGET ${VIEWER_BINARY_NAME} PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (BUGSPLAT_DB) +endif (USE_BUGSPLAT) # add package files file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST @@ -2018,11 +2016,11 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLAPPEARANCE_LIBRARIES} ) -if (BUGSPLAT_DB) +if (USE_BUGSPLAT) target_link_libraries(${VIEWER_BINARY_NAME} ${BUGSPLAT_LIBRARIES} ) -endif (BUGSPLAT_DB) +endif (USE_BUGSPLAT) set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Path to artwork files.") @@ -2206,7 +2204,7 @@ endif (INSTALL) # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE) - if (NOT BUGSPLAT_DB) + if (NOT USE_BUGSPLAT) # Breakpad symbol-file generation set(SYMBOL_SEARCH_DIRS "") if (WINDOWS) @@ -2261,7 +2259,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}") endif (WINDOWS OR LINUX) - else (NOT BUGSPLAT_DB) + else (NOT USE_BUGSPLAT) # BugSplat symbol-file generation if (WINDOWS) # Just pack up a tarball containing only the .pdb file for the @@ -2345,9 +2343,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE if (LINUX) # TBD endif (LINUX) - endif (NOT BUGSPLAT_DB) + endif (NOT USE_BUGSPLAT) - # for both BUGSPLAT_DB and Breakpad + # for both Bugsplat and Breakpad add_dependencies(llpackage generate_symbols) endif () 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 diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 2f3e5db84f..0a01113224 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -145,10 +145,10 @@ void LLWatchdogTimeout::ping(const std::string& state) } // LLWatchdog -LLWatchdog::LLWatchdog() : - mSuspectsAccessMutex(), - mTimer(NULL), - mLastClockCount(0) +LLWatchdog::LLWatchdog() + :mSuspectsAccessMutex() + ,mTimer(NULL) + ,mLastClockCount(0) { } diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 8344cead57..7ac1f1db23 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -13,7 +13,7 @@ include(LLXML) include(Linking) include(Tut) include(LLAddBuildTest) - +include(bugsplat) include(GoogleMock) include_directories( @@ -82,6 +82,10 @@ list(APPEND test_SOURCE_FILES ${test_HEADER_FILES}) add_executable(lltest ${test_SOURCE_FILES}) +if (USE_BUGSPLAT) + set_target_properties(lltest PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +endif (USE_BUGSPLAT) + target_link_libraries(lltest ${LLDATABASE_LIBRARIES} ${LLINVENTORY_LIBRARIES} diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 125de72b79..5dabcbbc58 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -75,7 +75,10 @@ #include -void wouldHaveCrashed(const std::string& message); +void wouldHaveCrashed(const std::string& message) +{ + tut::fail("fatal error message: " + message); +} namespace tut { @@ -506,11 +509,6 @@ void stream_groups(std::ostream& s, const char* app) } } -void wouldHaveCrashed(const std::string& message) -{ - tut::fail("fatal error message: " + message); -} - static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL; int main(int argc, char **argv) -- 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/llcommon/llerror.cpp | 18 +++++++-------- indra/llcommon/llerror.h | 6 +++-- indra/llcommon/llerrorcontrol.h | 11 ++++++--- indra/llcommon/tests/llerror_test.cpp | 8 +++++-- indra/llcommon/tests/wrapllerrs.h | 8 +++---- indra/newview/llappviewer.cpp | 43 ++++++++++++----------------------- indra/newview/llappviewermacosx.cpp | 6 ++--- indra/test/test.cpp | 7 +++--- 8 files changed, 51 insertions(+), 56 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 77d7fe1b24..6fa9e590cb 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -719,7 +719,7 @@ namespace LLError commonInit(user_dir, app_dir, log_to_stderr); } - void overrideCrashOnError(const FatalFunction& fatal_function) + void setFatalHandler(const FatalFunction& fatal_function) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); s->mCrashFunction = fatal_function; @@ -1306,12 +1306,12 @@ namespace LLError return ; } - bool Log::flush(std::ostringstream* out, const CallSite& site) + ErrCrashHandlerResult Log::flush(std::ostringstream* out, const CallSite& site) { LLMutexTrylock lock(&gLogMutex,5); if (!lock.isLocked()) { - return false; // because this wasn't logged, it cannot be fatal + return ERR_DO_NOT_CRASH; // because this wasn't logged, it cannot be fatal } // If we hit a logging request very late during shutdown processing, @@ -1319,7 +1319,7 @@ namespace LLError // DO NOT resurrect them. if (Settings::wasDeleted() || Globals::wasDeleted()) { - return false; // because this wasn't logged, it cannot be fatal + return ERR_DO_NOT_CRASH; // because this wasn't logged, it cannot be fatal } Globals* g = Globals::getInstance(); @@ -1353,7 +1353,7 @@ namespace LLError } else { - return false; // because this wasn't logged, it cannot be fatal + return ERR_DO_NOT_CRASH; // because this wasn't logged, it cannot be fatal } } else @@ -1369,20 +1369,18 @@ namespace LLError if (site.mLevel == LEVEL_ERROR) { - g->mFatalMessage = message; if (s->mCrashFunction) { - s->mCrashFunction(message); - return false; // because an override is in effect + return s->mCrashFunction(message); } else { - return true; // calling macro should crash + return ERR_CRASH; // calling macro should crash } } else { - return false; // not ERROR, so do not crash + return ERR_DO_NOT_CRASH; // not ERROR, so do not crash } } } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 07aa5c6f8b..2a73ccb36a 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -194,6 +194,8 @@ namespace LLError struct CallSite; + enum ErrCrashHandlerResult { ERR_DO_NOT_CRASH, ERR_CRASH }; + class LL_COMMON_API Log { public: @@ -203,7 +205,7 @@ namespace LLError static void flush(std::ostringstream* out, char* message); // returns false iff the calling macro should crash - static bool flush(std::ostringstream*, const CallSite&); + static ErrCrashHandlerResult flush(std::ostringstream*, const CallSite&); static std::string demangle(const char* mangled); }; @@ -386,7 +388,7 @@ volatile extern int* gCauseCrash; #define LL_ENDL \ LLError::End(); \ - if (LLError::Log::flush(_out, _site)) \ + if (LLError::ERR_CRASH == LLError::Log::flush(_out, _site)) \ LLERROR_CRASH \ } \ } while(0) diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index af46430f74..2fa220ba5a 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -93,16 +93,21 @@ namespace LLError Control functions. */ - typedef boost::function FatalFunction; + // A FatalFunction is called if set using setFatalHandler; its return controls + // whether or not the calling error logging code should crash. + // ERR_DO_NOT_CRASH should be used only in test code. + typedef boost::function FatalFunction; + /// Override the default behavior of crashing on LL_ERRS; this should NEVER be used except in test code - LL_COMMON_API void overrideCrashOnError(const FatalFunction&); + LL_COMMON_API void setFatalHandler(const FatalFunction&); // The fatal function will be called when an message of LEVEL_ERROR // is logged. Note: supressing a LEVEL_ERROR message from being logged // (by, for example, setting a class level to LEVEL_NONE), will keep // the that message from causing the fatal funciton to be invoked. + // The - /// Undo the effect of the overrideCrashOnError above + /// Undo the effect of the setFatalHandler above LL_COMMON_API void restoreCrashOnError(); LL_COMMON_API std::string getFatalMessage(); diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 2f8923d2de..9dcb5c145f 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -70,7 +70,11 @@ namespace namespace { static bool fatalWasCalled; - void fatalCall(const std::string&) { fatalWasCalled = true; } + LLError::ErrCrashHandlerResult fatalCall(const std::string&) + { + fatalWasCalled = true; + return LLError::ERR_DO_NOT_CRASH; + } } namespace tut @@ -120,7 +124,7 @@ namespace tut mPriorErrorSettings = LLError::saveAndResetSettings(); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); - LLError::overrideCrashOnError(fatalCall); + LLError::setFatalHandler(fatalCall); LLError::addRecorder(mRecorder); } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index fedc17dbe9..a412e12a04 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -46,7 +46,7 @@ // statically reference the function in test.cpp... it's short, we could // replicate, but better to reuse -extern void wouldHaveCrashed(const std::string& message); +extern LLError::ErrCrashHandlerResult wouldHaveCrashed(const std::string& message); struct WrapLLErrs { @@ -57,7 +57,7 @@ struct WrapLLErrs :mPriorErrorSettings(LLError::saveAndResetSettings()) { // Make LL_ERRS call our own operator() method - LLError::overrideCrashOnError(boost::bind(&WrapLLErrs::operator(), this, _1)); + LLError::setFatalHandler(boost::bind(&WrapLLErrs::operator(), this, _1)); } ~WrapLLErrs() @@ -71,7 +71,7 @@ struct WrapLLErrs FatalException(const std::string& what): LLException(what) {} }; - void operator()(const std::string& message) + LLError::ErrCrashHandlerResult operator()(const std::string& message) { // Save message for later in case consumer wants to sense the result directly error = message; @@ -201,7 +201,7 @@ public: mOldSettings(LLError::saveAndResetSettings()), mRecorder(new CaptureLogRecorder()) { - LLError::overrideCrashOnError(wouldHaveCrashed); + LLError::setFatalHandler(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } 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 { diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 3111540a13..9c2e6eadca 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -188,17 +188,17 @@ CrashMetadataSingleton::CrashMetadataSingleton() LLSD info; if (! static_file.is_open()) { - LL_INFOS() << "Can't open '" << staticDebugPathname + LL_WARNS() << "Can't open '" << staticDebugPathname << "'; no metadata about previous run" << LL_ENDL; } else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED)) { - LL_INFOS() << "Can't parse '" << staticDebugPathname + LL_WARNS() << "Can't parse '" << staticDebugPathname << "'; no metadata about previous run" << LL_ENDL; } else { - LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL; + LL_INFOS() << "Previous run metadata from '" << staticDebugPathname << "':" << LL_ENDL; logFilePathname = get_metadata(info, "SLLog"); userSettingsPathname = get_metadata(info, "SettingsFilename"); OSInfo = get_metadata(info, "OSInfo"); diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 5dabcbbc58..4f966aede8 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -75,9 +75,10 @@ #include -void wouldHaveCrashed(const std::string& message) +LLError::ErrCrashHandlerResult wouldHaveCrashed(const std::string& message) { tut::fail("fatal error message: " + message); + return LLError::ERR_DO_NOT_CRASH; } namespace tut @@ -149,7 +150,7 @@ public: mOldSettings(LLError::saveAndResetSettings()), mRecorder(new RecordToTempFile(pool)) { - LLError::overrideCrashOnError(wouldHaveCrashed); + LLError::setFatalHandler(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } @@ -530,7 +531,7 @@ int main(int argc, char **argv) LLError::initForApplication(".", ".", false /* do not log to stderr */); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); } - LLError::overrideCrashOnError(wouldHaveCrashed); + LLError::setFatalHandler(wouldHaveCrashed); std::string test_app_name(argv[0]); std::string test_log = test_app_name + ".log"; LLFile::remove(test_log); -- 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/llcommon/llerror.cpp | 18 +++++++++--------- indra/llcommon/llerror.h | 6 +++--- indra/llcommon/llerrorcontrol.h | 26 ++++++++++++++------------ indra/llcommon/llleap.cpp | 32 +++++++++++++++++++++++++++++++- indra/llcommon/tests/llerror_test.cpp | 4 ++-- indra/llcommon/tests/wrapllerrs.h | 23 +++++++++++++---------- indra/newview/llappviewer.cpp | 4 ++-- indra/test/test.cpp | 6 +++--- 8 files changed, 77 insertions(+), 42 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 6fa9e590cb..5f3edf7f84 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -483,7 +483,7 @@ namespace LLError LevelMap mTagLevelMap; std::map mUniqueLogMessages; - LLError::FatalFunction mCrashFunction; + LLError::FatalHook mFatalHook; LLError::TimeFunction mTimeFunction; Recorders mRecorders; @@ -523,7 +523,7 @@ namespace LLError mFileLevelMap(), mTagLevelMap(), mUniqueLogMessages(), - mCrashFunction(NULL), + mFatalHook(NULL), mTimeFunction(NULL), mRecorders(), mFileRecorder(), @@ -719,16 +719,16 @@ namespace LLError commonInit(user_dir, app_dir, log_to_stderr); } - void setFatalHandler(const FatalFunction& fatal_function) + void setFatalHook(const FatalHook& fatal_hook) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - s->mCrashFunction = fatal_function; + s->mFatalHook = fatal_hook; } - void restoreCrashOnError() + FatalHook getFatalHook() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - s->mCrashFunction = NULL; + return s->mFatalHook; } std::string getFatalMessage() @@ -1306,7 +1306,7 @@ namespace LLError return ; } - ErrCrashHandlerResult Log::flush(std::ostringstream* out, const CallSite& site) + ErrFatalHookResult Log::flush(std::ostringstream* out, const CallSite& site) { LLMutexTrylock lock(&gLogMutex,5); if (!lock.isLocked()) @@ -1369,9 +1369,9 @@ namespace LLError if (site.mLevel == LEVEL_ERROR) { - if (s->mCrashFunction) + if (s->mFatalHook) { - return s->mCrashFunction(message); + return s->mFatalHook(message); } else { diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 2a73ccb36a..6bdb2e852f 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -194,7 +194,7 @@ namespace LLError struct CallSite; - enum ErrCrashHandlerResult { ERR_DO_NOT_CRASH, ERR_CRASH }; + enum ErrFatalHookResult { ERR_DO_NOT_CRASH, ERR_CRASH }; class LL_COMMON_API Log { @@ -205,7 +205,7 @@ namespace LLError static void flush(std::ostringstream* out, char* message); // returns false iff the calling macro should crash - static ErrCrashHandlerResult flush(std::ostringstream*, const CallSite&); + static ErrFatalHookResult flush(std::ostringstream*, const CallSite&); static std::string demangle(const char* mangled); }; @@ -272,7 +272,7 @@ namespace LLError //when LLAppViewer::handleViewerCrash() is triggered. // //Note: to be simple, efficient and necessary to keep track of correct call stacks, - //LLCallStacks is designed not to be thread-safe. + //LLCallStacks is designed not to be thread-safe. //so try not to use it in multiple parallel threads at same time. //Used in a single thread at a time is fine. class LL_COMMON_API LLCallStacks diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 2fa220ba5a..e7c5241cc9 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -93,22 +93,24 @@ namespace LLError Control functions. */ - // A FatalFunction is called if set using setFatalHandler; its return controls + // A FatalHook is called if set using setFatalHook; its return controls // whether or not the calling error logging code should crash. // ERR_DO_NOT_CRASH should be used only in test code. - typedef boost::function FatalFunction; - - - /// Override the default behavior of crashing on LL_ERRS; this should NEVER be used except in test code - LL_COMMON_API void setFatalHandler(const FatalFunction&); - // The fatal function will be called when an message of LEVEL_ERROR + typedef boost::function FatalHook; + + /// Supplement and control the default behavior of crashing on LL_ERRS + /// This may be used to suppress crashes only in test code; + /// otherwise, the FatalHook should always either return + /// the result from the previous hook (see getFatalHook below), + /// or return LLError::ERR_CRASH + LL_COMMON_API void setFatalHook(const FatalHook& fatal_hook); + // The fatal_hook function will be called when an message of LEVEL_ERROR // is logged. Note: supressing a LEVEL_ERROR message from being logged - // (by, for example, setting a class level to LEVEL_NONE), will keep - // the that message from causing the fatal funciton to be invoked. - // The + // (by, for example, setting a class level to LEVEL_NONE), will also + // prevent the fatal_hook being called and the resulting deliberate crash - /// Undo the effect of the setFatalHandler above - LL_COMMON_API void restoreCrashOnError(); + /// Retrieve the previously-set FatalHook + LL_COMMON_API FatalHook getFatalHook(); LL_COMMON_API std::string getFatalMessage(); // Retrieve the message last passed to LL_ERRS, if any diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index bf20c87c89..161d25bc34 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -59,7 +59,7 @@ public: // pump name -- so it should NOT need tweaking for uniqueness. mReplyPump(LLUUID::generateNewID().asString()), mExpect(0), - + mPrevFatalHook(LLError::getFatalHook()), // Instantiate a distinct LLLeapListener for this plugin. (Every // plugin will want its own collection of managed listeners, etc.) // Pass it a callback to our connect() method, so it can send events @@ -145,6 +145,9 @@ public: mStderrConnection = childerr.getPump() .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1)); + // For our lifespan, intercept any LL_ERRS so we can notify plugin + LLError::setFatalHook(boost::bind(&LLLeapImpl::fatalHook, this, _1)); + // Send child a preliminary event reporting our own reply-pump name -- // which would otherwise be pretty tricky to guess! wstdin(mReplyPump.getName(), @@ -159,6 +162,8 @@ public: virtual ~LLLeapImpl() { LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL; + // Restore original FatalHook + LLError::setFatalHook(mPrevFatalHook); } // Listener for failed launch attempt @@ -372,6 +377,30 @@ public: return false; } + LLError::ErrFatalHookResult fatalHook(const std::string& error) + { + // Notify plugin + LLSD event; + event["type"] = "error"; + event["error"] = error; + mReplyPump.post(event); + + // All the above really accomplished was to buffer the serialized + // event in our WritePipe. Have to pump mainloop a couple times to + // really write it out there... but time out in case we can't write. + LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); + LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); + LLSD nop; + F64 until = (LLTimer::getElapsedSeconds() + 2).value(); + while (childin.size() && LLTimer::getElapsedSeconds() < until) + { + mainloop.post(nop); + } + + // forward the call to the previous FatalHook, default to crashing if there isn't one + return mPrevFatalHook ? mPrevFatalHook(error) : LLError::ERR_CRASH; + } + private: /// We always want to listen on mReplyPump with wstdin(); under some /// circumstances we'll also echo other LLEventPumps to the plugin. @@ -392,6 +421,7 @@ private: mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection; boost::scoped_ptr mBlocker; LLProcess::ReadPipe::size_type mExpect; + LLError::FatalHook mPrevFatalHook; boost::scoped_ptr mListener; }; diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 9dcb5c145f..9895abc1f3 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -70,7 +70,7 @@ namespace namespace { static bool fatalWasCalled; - LLError::ErrCrashHandlerResult fatalCall(const std::string&) + LLError::ErrFatalHookResult fatalHook(const std::string&) { fatalWasCalled = true; return LLError::ERR_DO_NOT_CRASH; @@ -124,7 +124,7 @@ namespace tut mPriorErrorSettings = LLError::saveAndResetSettings(); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); - LLError::setFatalHandler(fatalCall); + LLError::setFatalHook(fatalHook); LLError::addRecorder(mRecorder); } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index a412e12a04..a6c44d5fdd 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -46,7 +46,7 @@ // statically reference the function in test.cpp... it's short, we could // replicate, but better to reuse -extern LLError::ErrCrashHandlerResult wouldHaveCrashed(const std::string& message); +extern LLError::ErrFatalHookResult wouldHaveCrashed(const std::string& message); struct WrapLLErrs { @@ -55,14 +55,15 @@ struct WrapLLErrs // stderr. Otherwise, expected llerrs (LL_ERRS) messages clutter the // console output of successful tests, potentially confusing things. :mPriorErrorSettings(LLError::saveAndResetSettings()) + ,mPriorFatalHook(LLError::getFatalHook()) { // Make LL_ERRS call our own operator() method - LLError::setFatalHandler(boost::bind(&WrapLLErrs::operator(), this, _1)); + LLError::setFatalHook(boost::bind(&WrapLLErrs::operator(), this, _1)); } ~WrapLLErrs() { - LLError::restoreCrashOnError(); + LLError::setFatalHook(mPriorFatalHook); LLError::restoreSettings(mPriorErrorSettings); } @@ -71,7 +72,7 @@ struct WrapLLErrs FatalException(const std::string& what): LLException(what) {} }; - LLError::ErrCrashHandlerResult operator()(const std::string& message) + LLError::ErrFatalHookResult operator()(const std::string& message) { // Save message for later in case consumer wants to sense the result directly error = message; @@ -107,7 +108,7 @@ struct WrapLLErrs std::string error; LLError::SettingsStoragePtr mPriorErrorSettings; - LLError::FatalFunction mPriorFatal; + LLError::FatalHook mPriorFatalHook; }; /** @@ -197,11 +198,12 @@ public: // with that output. If it turns out that saveAndResetSettings() has // some bad effect, give up and just let the DEBUG level log messages // display. - : boost::noncopyable(), - mOldSettings(LLError::saveAndResetSettings()), - mRecorder(new CaptureLogRecorder()) + : boost::noncopyable() + , mOldSettings(LLError::saveAndResetSettings()) + , mPriorFatalHook(LLError::getFatalHook()) + , mRecorder(new CaptureLogRecorder()) { - LLError::setFatalHandler(wouldHaveCrashed); + LLError::setFatalHook(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } @@ -210,7 +212,7 @@ public: { LLError::removeRecorder(mRecorder); LLError::restoreSettings(mOldSettings); - LLError::restoreCrashOnError(); + LLError::setFatalHook(mPriorFatalHook); } /// Don't assume the message we want is necessarily the LAST log message @@ -228,6 +230,7 @@ public: private: LLError::SettingsStoragePtr mOldSettings; + LLError::FatalHook mPriorFatalHook; LLError::RecorderPtr mRecorder; }; 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, diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 4f966aede8..52ac855d9f 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -75,7 +75,7 @@ #include -LLError::ErrCrashHandlerResult wouldHaveCrashed(const std::string& message) +LLError::ErrFatalHookResult wouldHaveCrashed(const std::string& message) { tut::fail("fatal error message: " + message); return LLError::ERR_DO_NOT_CRASH; @@ -150,7 +150,7 @@ public: mOldSettings(LLError::saveAndResetSettings()), mRecorder(new RecordToTempFile(pool)) { - LLError::setFatalHandler(wouldHaveCrashed); + LLError::setFatalHook(wouldHaveCrashed); LLError::setDefaultLevel(level); LLError::addRecorder(mRecorder); } @@ -531,7 +531,7 @@ int main(int argc, char **argv) LLError::initForApplication(".", ".", false /* do not log to stderr */); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); } - LLError::setFatalHandler(wouldHaveCrashed); + LLError::setFatalHook(wouldHaveCrashed); std::string test_app_name(argv[0]); std::string test_log = test_app_name + ".log"; LLFile::remove(test_log); -- cgit v1.2.3 From 46fb225134ef871a686d0571cc55256923eee110 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 21 May 2019 12:09:26 -0400 Subject: suppress unreachable code warning because tut::fail triggers it --- indra/test/test.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'indra') diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 52ac855d9f..9d327ff3be 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -57,16 +57,11 @@ #include #endif -#if LL_MSVC -#pragma warning (push) +#if LL_WINDOWS #pragma warning (disable : 4702) // warning C4702: unreachable code #endif #include #include -#if LL_MSVC -#pragma warning (pop) -#endif - #include #include #include -- 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') 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/llcommon/llapp.cpp | 5 +++++ indra/newview/CMakeLists.txt | 2 +- indra/newview/llappdelegate-objc.mm | 2 ++ indra/newview/llappviewer.cpp | 10 ++-------- indra/newview/llappviewerwin32.cpp | 3 +-- indra/newview/llviewerwindow.cpp | 3 ++- 6 files changed, 13 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 421af3006e..34c969437b 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -526,7 +526,12 @@ void LLApp::setupErrorHandling(bool second_instance) #endif // LL_LINUX #endif // ! LL_WINDOWS + +#ifdef LL_BUGSPLAT + // do not start our own error thread +#else // ! LL_BUGSPLAT startErrorThread(); +#endif } void LLApp::startErrorThread() diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index bbfa838827..fd520d2c6f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1729,7 +1729,7 @@ endif (SDL_FOUND) if (USE_BUGSPLAT) set_property(TARGET ${VIEWER_BINARY_NAME} - PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") + PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") endif (USE_BUGSPLAT) # add package files diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 47fde299c7..30bfe1f439 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -66,6 +66,7 @@ constructViewer(); #if defined(LL_BUGSPLAT) + infos("bugsplat setup"); // Engage BugsplatStartupManager *before* calling initViewer() to handle // any crashes during initialization. // https://www.bugsplat.com/docs/platforms/os-x#initialization @@ -74,6 +75,7 @@ [BugsplatStartupManager sharedManager].delegate = self; [[BugsplatStartupManager sharedManager] start]; #endif + infos("post-bugsplat setup"); frameTimer = nil; 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) diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d208e135bb..6a6cc225d4 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -802,8 +802,7 @@ bool LLAppViewerWin32::beingDebugged() bool LLAppViewerWin32::restoreErrorTrap() { - return true; - //return LLWinDebug::checkExceptionHandler(); + return false; } void LLAppViewerWin32::initCrashReporting(bool reportFreeze) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c214984e1d..b0f5b550e6 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1791,7 +1791,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) if (!LLAppViewer::instance()->restoreErrorTrap()) { - LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL; + // this always happens, so downgrading it to INFO + LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL; } const bool do_not_enforce = false; -- cgit v1.2.3 From b6f1529b5abaf36b15efb6d9215bcc89e6a3f167 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 6 Jun 2019 09:25:15 -0400 Subject: remove the old crash logger modules when using BugSplat --- indra/CMakeLists.txt | 40 +++++++++++++++++++++++----------------- indra/newview/CMakeLists.txt | 28 +++++++++++++++++++--------- 2 files changed, 42 insertions(+), 26 deletions(-) (limited to 'indra') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index cf6029c4ae..4dd2dcc2e9 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -60,29 +60,18 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) endif (ENABLE_MEDIA_PLUGINS) if (LINUX) - add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) if (INSTALL_PROPRIETARY) include(LLAppearanceUtility) add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) endif (INSTALL_PROPRIETARY) - add_dependencies(viewer linux-crash-logger-strip-target) -elseif (DARWIN) - add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) - add_dependencies(viewer mac-crash-logger) -elseif (WINDOWS) - add_subdirectory(${VIEWER_PREFIX}win_crash_logger) - # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake - if (EXISTS ${VIEWER_DIR}win_setup) - add_subdirectory(${VIEWER_DIR}win_setup) - endif (EXISTS ${VIEWER_DIR}win_setup) - # add_dependencies(viewer windows-setup windows-crash-logger) - add_dependencies(viewer windows-crash-logger) endif (LINUX) -add_subdirectory(${VIEWER_PREFIX}newview) -add_dependencies(viewer secondlife-bin) - -add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) +if (WINDOWS) + # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake + if (EXISTS ${VIEWER_DIR}win_setup) + add_subdirectory(${VIEWER_DIR}win_setup) + endif (EXISTS ${VIEWER_DIR}win_setup) +endif (WINDOWS) # sets the 'startup project' for debugging from visual studio. set_property( @@ -98,7 +87,24 @@ if (USE_BUGSPLAT) endif (BUGSPLAT_DB) else (USE_BUGSPLAT) message(STATUS "Not building with BugSplat") + if (LINUX) + add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) + add_dependencies(viewer linux-crash-logger-strip-target) + elseif (DARWIN) + add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) + add_dependencies(viewer mac-crash-logger) + elseif (WINDOWS) + add_subdirectory(${VIEWER_PREFIX}win_crash_logger) + # add_dependencies(viewer windows-setup windows-crash-logger) + add_dependencies(viewer windows-crash-logger) + endif (LINUX) endif (USE_BUGSPLAT) + +add_subdirectory(${VIEWER_PREFIX}newview) +add_dependencies(viewer secondlife-bin) + +add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) + if (LL_TESTS) # Define after the custom targets are created so # individual apps can add themselves as dependencies diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fd520d2c6f..40ff1263f2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1808,9 +1808,12 @@ if (WINDOWS) media_plugin_libvlc media_plugin_example winmm_shim - windows-crash-logger ) + if (NOT USE_BUGSPLAT) + LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger) + endif (NOT USE_BUGSPLAT) + if (ADDRESS_SIZE EQUAL 64) list(APPEND COPY_INPUT_DEPENDENCIES ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll @@ -1864,10 +1867,11 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts) endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) - add_dependencies(${VIEWER_BINARY_NAME} - SLPlugin - windows-crash-logger - ) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin) + + if (NOT USE_BUGSPLAT) + add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger) + endif (NOT USE_BUGSPLAT) # sets the 'working directory' for debugging from visual studio. # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) @@ -2031,13 +2035,16 @@ if (LINUX) # These are the generated targets that are copied to package/ set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} - linux-crash-logger SLPlugin media_plugin_gstreamer010 media_plugin_libvlc llcommon ) + if (NOT USE_BUGSPLAT) + LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger) + endif (NOT USE_BUGSPLAT) + add_custom_command( OUTPUT ${product}.tar.bz2 COMMAND ${PYTHON_EXECUTABLE} @@ -2162,8 +2169,11 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger) - add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef) + + if (NOT USE_BUGSPLAT) + add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) + endif (USE_BUGSPLAT) if (ENABLE_SIGNING) set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") @@ -2221,7 +2231,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") - set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger") + set(VIEWER_EXE_GLOBS "'${product}' SLPlugin") set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger") set(VIEWER_LIB_GLOB "*.dylib") endif (DARWIN) -- cgit v1.2.3 From 4c525832cc7a32abce94823ac9c8ec2c4d510498 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 12 Jun 2019 08:49:59 -0400 Subject: remove old crash logger more --- indra/newview/llappviewermacosx.cpp | 9 +++++++-- indra/newview/llappviewerwin32.cpp | 6 +----- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 9c2e6eadca..4a519b944b 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -241,7 +241,7 @@ bool LLAppViewerMacOSX::init() { bool success = LLAppViewer::init(); -#if LL_SEND_CRASH_REPORTS +#if !defined LL_BUGSPLAT && LL_SEND_CRASH_REPORTS if (success) { LLAppViewer* pApp = LLAppViewer::instance(); @@ -368,6 +368,7 @@ bool LLAppViewerMacOSX::restoreErrorTrap() void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) { +#ifndef LL_BUGSPLAT std::string command_str = "mac-crash-logger.app"; std::stringstream pid_str; @@ -379,6 +380,9 @@ void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) LL_WARNS() << "about to launch mac-crash-logger" << pid_str.str() << " " << logdir << " " << appname << LL_ENDL; launchApplication(&command_str, &args); +#else + LL_DEBUGS("InitOSX") << "using BugSplat instead of legacy crash logger" << LL_ENDL; +#endif // ! LL_BUGSPLAT } std::string LLAppViewerMacOSX::generateSerialNumber() @@ -390,7 +394,8 @@ std::string LLAppViewerMacOSX::generateSerialNumber() CFStringRef serialNumber = NULL; io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); - if (platformExpert) { + if (platformExpert) + { serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 6a6cc225d4..235f7cc8ed 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -174,7 +174,7 @@ static void exceptionTerminateHandler() 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 } @@ -362,10 +362,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, 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); -- cgit v1.2.3 From 9627eddb102580703d6229bc6e827696dcb9e9d4 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 12 Jun 2019 08:51:01 -0400 Subject: document that old crash logger is not used in production builds --- indra/linux_crash_logger/README.txt | 3 +++ indra/llcrashlogger/README.txt | 3 +++ indra/mac_crash_logger/README.txt | 3 +++ indra/win_crash_logger/README.txt | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 indra/linux_crash_logger/README.txt create mode 100644 indra/llcrashlogger/README.txt create mode 100644 indra/mac_crash_logger/README.txt create mode 100644 indra/win_crash_logger/README.txt (limited to 'indra') diff --git a/indra/linux_crash_logger/README.txt b/indra/linux_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/linux_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/llcrashlogger/README.txt b/indra/llcrashlogger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/llcrashlogger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/mac_crash_logger/README.txt b/indra/mac_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/mac_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/win_crash_logger/README.txt b/indra/win_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/win_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. -- cgit v1.2.3 From 83ec9ebfbd602771dbc45c08fe203044b5ce3527 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 24 Sep 2019 10:15:20 -0400 Subject: log calls that modify the fatal error hook --- indra/llcommon/llerror.cpp | 2 ++ indra/llcommon/tests/llerror_test.cpp | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 5f3edf7f84..da68117ff5 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -723,11 +723,13 @@ namespace LLError { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); s->mFatalHook = fatal_hook; + LL_DEBUGS("FatalHook") << "set fatal hook to " << fatal_hook << LL_ENDL; } FatalHook getFatalHook() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); + LL_DEBUGS("FatalHook") << "read fatal hook " << s->mFatalHook << LL_ENDL; return s->mFatalHook; } diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 9895abc1f3..cdc2bf8c87 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -781,30 +781,33 @@ namespace tut // proper cached, efficient lookup of filtering void ErrorTestObject::test<15>() { - LLError::setDefaultLevel(LLError::LEVEL_NONE); + LLError::setDefaultLevel(LLError::LEVEL_NONE); + + // Note that the setFatalHook in the ErrorTestData constructor + // increments the shouldLogCallCount TestAlpha::doInfo(); ensure_message_count(0); - ensure_equals("first check", LLError::shouldLogCallCount(), 1); + ensure_equals("first check", LLError::shouldLogCallCount(), 2); TestAlpha::doInfo(); ensure_message_count(0); - ensure_equals("second check", LLError::shouldLogCallCount(), 1); + ensure_equals("second check", LLError::shouldLogCallCount(), 2); LLError::setClassLevel("TestAlpha", LLError::LEVEL_DEBUG); TestAlpha::doInfo(); ensure_message_count(1); - ensure_equals("third check", LLError::shouldLogCallCount(), 2); + ensure_equals("third check", LLError::shouldLogCallCount(), 3); TestAlpha::doInfo(); ensure_message_count(2); - ensure_equals("fourth check", LLError::shouldLogCallCount(), 2); + ensure_equals("fourth check", LLError::shouldLogCallCount(), 3); LLError::setClassLevel("TestAlpha", LLError::LEVEL_WARN); TestAlpha::doInfo(); ensure_message_count(2); - ensure_equals("fifth check", LLError::shouldLogCallCount(), 3); + ensure_equals("fifth check", LLError::shouldLogCallCount(), 4); TestAlpha::doInfo(); ensure_message_count(2); - ensure_equals("sixth check", LLError::shouldLogCallCount(), 3); + ensure_equals("sixth check", LLError::shouldLogCallCount(), 4); } template<> template<> -- 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/llcommon/llerror.cpp | 4 ++-- indra/llcommon/llleap.cpp | 2 ++ indra/newview/llappviewer.cpp | 7 ++++++- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index da68117ff5..df8443bd7a 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -723,13 +723,13 @@ namespace LLError { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); s->mFatalHook = fatal_hook; - LL_DEBUGS("FatalHook") << "set fatal hook to " << fatal_hook << LL_ENDL; + LL_DEBUGS("FatalHook") << "set fatal hook to " << reinterpret_cast(fatal_hook) << LL_ENDL; } FatalHook getFatalHook() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - LL_DEBUGS("FatalHook") << "read fatal hook " << s->mFatalHook << LL_ENDL; + LL_DEBUGS("FatalHook") << "read fatal hook " << reinterpret_cast(s->mFatalHook) << LL_ENDL; return s->mFatalHook; } diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 161d25bc34..bb32c73d04 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -67,6 +67,7 @@ public: // this class or method name. mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2))) { + LL_DEBUGS("FatalHook") << "previous fatal hook was " <(mPrevFatalHook) << LL_ENDL; // Rule out unpopulated Params block if (! cparams.executable.isProvided()) { @@ -398,6 +399,7 @@ public: } // forward the call to the previous FatalHook, default to crashing if there isn't one + LL_DEBUGS("FatalHook") << "end" << LL_ENDL; return mPrevFatalHook ? mPrevFatalHook(error) : LLError::ERR_CRASH; } 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 581b6fe5234110efa9c27751ed2c9e062ae8f248 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 24 Sep 2019 15:08:45 -0400 Subject: simplify function pointer logging --- indra/llcommon/llerror.cpp | 10 ++++++---- indra/llcommon/llleap.cpp | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index df8443bd7a..1f947a0a74 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -722,14 +722,16 @@ namespace LLError void setFatalHook(const FatalHook& fatal_hook) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); + LL_DEBUGS("FatalHook") << "set fatal hook to "(fatal_hook ? "non-null" : "null") + << " was " << (s->mFatalHook ? "non-null" : "null") + << LL_ENDL; s->mFatalHook = fatal_hook; - LL_DEBUGS("FatalHook") << "set fatal hook to " << reinterpret_cast(fatal_hook) << LL_ENDL; - } - + } + FatalHook getFatalHook() { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - LL_DEBUGS("FatalHook") << "read fatal hook " << reinterpret_cast(s->mFatalHook) << LL_ENDL; + LL_DEBUGS("FatalHook") << "read fatal hook was " << (s->mFatalHook ? "non-null" : "null") << LL_ENDL; return s->mFatalHook; } diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index bb32c73d04..1c0678e453 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -67,7 +67,7 @@ public: // this class or method name. mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2))) { - LL_DEBUGS("FatalHook") << "previous fatal hook was " <(mPrevFatalHook) << LL_ENDL; + LL_DEBUGS("FatalHook") << "previous fatal hook was " << (mPrevFatalHook ? "non-null" : "null") << LL_ENDL; // Rule out unpopulated Params block if (! cparams.executable.isProvided()) { -- cgit v1.2.3 From 092bf4220eeaea0ae7765ea3cb49f122fb3e3dff Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 24 Sep 2019 15:33:42 -0400 Subject: further simplify function pointer logging --- indra/llcommon/llerror.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 1f947a0a74..327c3ad537 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -722,7 +722,7 @@ namespace LLError void setFatalHook(const FatalHook& fatal_hook) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - LL_DEBUGS("FatalHook") << "set fatal hook to "(fatal_hook ? "non-null" : "null") + LL_DEBUGS("FatalHook") << "set fatal hook to " << (fatal_hook ? "non-null" : "null") << " was " << (s->mFatalHook ? "non-null" : "null") << LL_ENDL; s->mFatalHook = fatal_hook; -- cgit v1.2.3 From bc8b55e1f2d772a657e4f7affc8a6c7d20f2c2e4 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 25 Sep 2019 12:56:05 -0400 Subject: remove fatal error hook usage from LLLeap (potential races for multiple processes) --- indra/llcommon/llleap.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 1c0678e453..8293c35516 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -59,7 +59,6 @@ public: // pump name -- so it should NOT need tweaking for uniqueness. mReplyPump(LLUUID::generateNewID().asString()), mExpect(0), - mPrevFatalHook(LLError::getFatalHook()), // Instantiate a distinct LLLeapListener for this plugin. (Every // plugin will want its own collection of managed listeners, etc.) // Pass it a callback to our connect() method, so it can send events @@ -67,7 +66,6 @@ public: // this class or method name. mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2))) { - LL_DEBUGS("FatalHook") << "previous fatal hook was " << (mPrevFatalHook ? "non-null" : "null") << LL_ENDL; // Rule out unpopulated Params block if (! cparams.executable.isProvided()) { @@ -146,9 +144,6 @@ public: mStderrConnection = childerr.getPump() .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1)); - // For our lifespan, intercept any LL_ERRS so we can notify plugin - LLError::setFatalHook(boost::bind(&LLLeapImpl::fatalHook, this, _1)); - // Send child a preliminary event reporting our own reply-pump name -- // which would otherwise be pretty tricky to guess! wstdin(mReplyPump.getName(), @@ -163,8 +158,6 @@ public: virtual ~LLLeapImpl() { LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL; - // Restore original FatalHook - LLError::setFatalHook(mPrevFatalHook); } // Listener for failed launch attempt @@ -378,31 +371,6 @@ public: return false; } - LLError::ErrFatalHookResult fatalHook(const std::string& error) - { - // Notify plugin - LLSD event; - event["type"] = "error"; - event["error"] = error; - mReplyPump.post(event); - - // All the above really accomplished was to buffer the serialized - // event in our WritePipe. Have to pump mainloop a couple times to - // really write it out there... but time out in case we can't write. - LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); - LLSD nop; - F64 until = (LLTimer::getElapsedSeconds() + 2).value(); - while (childin.size() && LLTimer::getElapsedSeconds() < until) - { - mainloop.post(nop); - } - - // forward the call to the previous FatalHook, default to crashing if there isn't one - LL_DEBUGS("FatalHook") << "end" << LL_ENDL; - return mPrevFatalHook ? mPrevFatalHook(error) : LLError::ERR_CRASH; - } - private: /// We always want to listen on mReplyPump with wstdin(); under some /// circumstances we'll also echo other LLEventPumps to the plugin. @@ -423,7 +391,6 @@ private: mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection; boost::scoped_ptr mBlocker; LLProcess::ReadPipe::size_type mExpect; - LLError::FatalHook mPrevFatalHook; boost::scoped_ptr mListener; }; -- cgit v1.2.3 From 79801c717de5de6b86b45eadf61b352c9951f61e Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 25 Sep 2019 12:57:51 -0400 Subject: fix warning about mismatched condition --- indra/newview/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 40ff1263f2..ab6b8c9c6e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2173,7 +2173,7 @@ if (DARWIN) if (NOT USE_BUGSPLAT) add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) - endif (USE_BUGSPLAT) + endif (NOT USE_BUGSPLAT) if (ENABLE_SIGNING) set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") -- cgit v1.2.3 From 66970f2a8c048647242887eb3f0c7fd974a303ac Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 25 Sep 2019 12:58:43 -0400 Subject: fix spurious per-frame warning about signal handlers in Windows --- indra/newview/llappviewerwin32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 235f7cc8ed..63de9af566 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -798,7 +798,7 @@ bool LLAppViewerWin32::beingDebugged() bool LLAppViewerWin32::restoreErrorTrap() { - return false; + return true; // we don't check for handler collisions on windows, so just say they're ok } void LLAppViewerWin32::initCrashReporting(bool reportFreeze) -- 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/llcommon/llapp.cpp | 5 +++++ indra/newview/llappviewer.cpp | 2 +- indra/newview/llappviewermacosx.cpp | 9 +++++---- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 34c969437b..27960371f1 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -779,7 +779,9 @@ void setup_signals() act.sa_flags = SA_SIGINFO; // Synchronous signals +# ifndef LL_BUGSPLAT sigaction(SIGABRT, &act, NULL); +# endif sigaction(SIGALRM, &act, NULL); sigaction(SIGBUS, &act, NULL); sigaction(SIGFPE, &act, NULL); @@ -816,7 +818,9 @@ void clear_signals() act.sa_flags = SA_SIGINFO; // Synchronous signals +# ifndef LL_BUGSPLAT sigaction(SIGABRT, &act, NULL); +# endif sigaction(SIGALRM, &act, NULL); sigaction(SIGBUS, &act, NULL); sigaction(SIGFPE, &act, NULL); @@ -869,6 +873,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) return; case SIGABRT: + // Note that this handler is not set for SIGABRT when using Bugsplat // Abort just results in termination of the app, no funky error handling. if (LLApp::sLogInSignal) { 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, diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 4a519b944b..efa1da054c 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -333,11 +333,12 @@ bool LLAppViewerMacOSX::restoreErrorTrap() unsigned int reset_count = 0; -#define SET_SIG(S) sigaction(SIGABRT, &act, &old_act); \ - if(act.sa_sigaction != old_act.sa_sigaction) \ - ++reset_count; +#define SET_SIG(SIGNAL) sigaction(SIGNAL, &act, &old_act); \ + if(act.sa_sigaction != old_act.sa_sigaction) ++reset_count; // Synchronous signals - SET_SIG(SIGABRT) +# ifndef LL_BUGSPLAT + SET_SIG(SIGABRT) // let bugsplat catch this +# endif SET_SIG(SIGALRM) SET_SIG(SIGBUS) SET_SIG(SIGFPE) -- cgit v1.2.3 From de5c07ec50d192e5a34cf710e2d1ed0c1127932f Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 7 Oct 2019 10:50:32 -0400 Subject: do not build the old crash logger when using bugsplat --- indra/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 4dd2dcc2e9..bd3bcd1173 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -46,7 +46,10 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) add_custom_target(viewer) +if (NOT USE_BUGSPLAT) add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) +endif (NOT USE_BUGSPLAT) + add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llui) add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components) -- cgit v1.2.3 From 2961fea6933621fc7c8ebc692d4c517d4aa93096 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 8 Oct 2019 10:15:19 -0400 Subject: Rename uploaded log file to get Bugsplat to server as text/plain --- indra/newview/llappdelegate-objc.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 30bfe1f439..ccab9173a9 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -301,9 +301,13 @@ struct AttachmentInfo // We "happen to know" that info[0].basename is "SecondLife.old" -- due to // the fact that BugsplatMac only notices a crash during the viewer run - // following the crash. Replace .old with .log to reduce confusion. + // following the crash. + // The Bugsplat service doesn't respect the MIME type above when returning + // the log data to a browser, so take this opportunity to rename the file + // from .old to _log.txt info[0].basename = - boost::filesystem::path(info[0].pathname).stem().string() + ".log"; + boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt"; + infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename); NSMutableArray *attachments = [[NSMutableArray alloc] init]; -- cgit v1.2.3 From 1082a886ce8ffe4a23943b8513356a509373f03c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 8 Oct 2019 10:15:47 -0400 Subject: tag initialization and bugsplat related logging --- indra/newview/llappviewermacosx.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index efa1da054c..999a475f8b 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -91,7 +91,7 @@ void constructViewer() // Set the working dir to /Contents/Resources if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1) { - LL_WARNS() << "Could not change directory to " + LL_WARNS("InitOSX") << "Could not change directory to " << gDirUtilp->getAppRODataDir() << ": " << strerror(errno) << LL_ENDL; } @@ -109,7 +109,7 @@ bool initViewer() bool ok = gViewerAppPtr->init(); if(!ok) { - LL_WARNS() << "Application init failed." << LL_ENDL; + LL_WARNS("InitOSX") << "Application init failed." << LL_ENDL; } else if (!gHandleSLURL.empty()) { @@ -172,7 +172,7 @@ class CrashMetadataSingleton: public CrashMetadata, public LLSingleton Date: Fri, 13 Dec 2019 12:20:50 -0500 Subject: clarify crash logger at startup --- indra/newview/llappviewermacosx.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 999a475f8b..5a0fe6ba0c 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -81,7 +81,8 @@ static void exceptionTerminateHandler() long *null_ptr; null_ptr = 0; *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. - //LLAppViewer::handleViewerCrash(); + LLAppViewer::handleViewerCrash(); + // we've probably been killed-off before now, but... gOldTerminateHandler(); // call old terminate() handler } @@ -99,7 +100,7 @@ void constructViewer() gViewerAppPtr = new LLAppViewerMacOSX(); // install unexpected exception handler - gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + //gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); } @@ -241,14 +242,11 @@ bool LLAppViewerMacOSX::init() { bool success = LLAppViewer::init(); -#if !defined LL_BUGSPLAT && LL_SEND_CRASH_REPORTS if (success) { LLAppViewer* pApp = LLAppViewer::instance(); pApp->initCrashReporting(); } -#endif - return success; } @@ -369,7 +367,10 @@ bool LLAppViewerMacOSX::restoreErrorTrap() void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) { -#ifndef LL_BUGSPLAT +#if defined LL_BUGSPLAT + LL_DEBUGS("InitOSX", "Bugsplat") << "using BugSplat crash logger" << LL_ENDL; +#elif LL_SEND_CRASH_REPORTS + LL_DEBUGS("InitOSX") << "Initializing legacy crash logger" << LL_ENDL; std::string command_str = "mac-crash-logger.app"; std::stringstream pid_str; @@ -382,7 +383,7 @@ void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze) << " " << logdir << " " << appname << LL_ENDL; launchApplication(&command_str, &args); #else - LL_DEBUGS("InitOSX") << "using BugSplat instead of legacy crash logger" << LL_ENDL; + LL_DEBUGS("InitOSX") << "No crash logger enabled" << LL_ENDL; #endif // ! LL_BUGSPLAT } -- cgit v1.2.3 From 5056ba6daafce402a5db6d2b75dceb20ed452e1d Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 16 Dec 2019 17:09:42 -0500 Subject: remove unused exception handler --- indra/newview/llappviewermacosx.cpp | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'indra') diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 5a0fe6ba0c..784a104573 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -68,25 +68,9 @@ namespace int gArgC; char** gArgV; LLAppViewerMacOSX* gViewerAppPtr = NULL; - - void (*gOldTerminateHandler)() = NULL; std::string gHandleSLURL; } -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 -} - void constructViewer() { // Set the working dir to /Contents/Resources @@ -99,9 +83,6 @@ void constructViewer() gViewerAppPtr = new LLAppViewerMacOSX(); - // install unexpected exception handler - //gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); - gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash); } -- cgit v1.2.3 From 17598f936bb6b099f21fc32aa80b68258cdfd0b9 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 16 Dec 2019 17:09:58 -0500 Subject: remove unused legacy crash logger --- indra/newview/viewer_manifest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a403760670..861c2120d8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1060,10 +1060,10 @@ class DarwinManifest(ViewerManifest): # our apps executable_path = {} - for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), - # plugin launcher - (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), - ): + embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] + if bugsplat_db: + embedded_apps.append(("mac_crash_logger", "mac-crash-logger.app")) + for app_bld_dir, app in embedded_apps: self.path2basename(os.path.join(os.pardir, app_bld_dir, self.args['configuration']), app) -- cgit v1.2.3 From 68105d9f06aea69980cf0402f00da0e2be450dd2 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 2 Apr 2020 10:55:31 -0700 Subject: Fixed -Wstring-plus-int related errors for compatibility with Xcode-11.4 --- indra/llcommon/llsdutil.cpp | 2 +- indra/newview/llcommandhandler.cpp | 2 +- indra/newview/llxmlrpclistener.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 9d00395c0a..859d2eb567 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -332,7 +332,7 @@ struct Data const char* name; } typedata[] = { -#define def(type) { LLSD::type, #type + 4 } +#define def(type) { LLSD::type, &#type[4] } def(TypeUndefined), def(TypeBoolean), def(TypeInteger), diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 76d965b1f1..23e2271eae 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -222,7 +222,7 @@ struct symbol_info #define ent(SYMBOL) \ { \ - #SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */ \ + &#SYMBOL[28], /* skip "LLCommandHandler::UNTRUSTED_" prefix */ \ SYMBOL \ } diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 7bc8af4a0b..7db2b88951 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -100,7 +100,7 @@ public: { // from curl.h // skip the "CURLE_" prefix for each of these strings -#define def(sym) (mMap[sym] = #sym + 6) +#define def(sym) (mMap[sym] = &#sym[6]) def(CURLE_OK); def(CURLE_UNSUPPORTED_PROTOCOL); /* 1 */ def(CURLE_FAILED_INIT); /* 2 */ -- cgit v1.2.3 From 9834955be072aeac3f886de2eaf1e075000108c7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 16 Jun 2020 14:41:28 -0400 Subject: SL-10297: remove mac-crash-logger from viewer-manifest, require the bugsplat library on Mac --- indra/cmake/bugsplat.cmake | 4 ++-- indra/newview/viewer_manifest.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 749ea05403..5f5cc51f63 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -13,8 +13,8 @@ if (USE_BUGSPLAT) ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib ) elseif (DARWIN) - find_library(BUGSPLAT_LIBRARIES BugsplatMac - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") + find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED + NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") else (WINDOWS) message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF") endif (WINDOWS) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ff0781991e..7cecfec1eb 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1063,7 +1063,7 @@ class DarwinManifest(ViewerManifest): # our apps executable_path = {} embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] - if bugsplat_db: + if not bugsplat_db: embedded_apps.append(("mac_crash_logger", "mac-crash-logger.app")) for app_bld_dir, app in embedded_apps: self.path2basename(os.path.join(os.pardir, -- cgit v1.2.3 From 6a9c89fd62ee458dff4f2ade76d44947b99e472a Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 25 Aug 2020 11:59:27 -0400 Subject: SL-10297 do not package win_crash_logger executable if using BugSplat --- indra/newview/viewer_manifest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2105b419e7..c636f1d910 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -673,10 +673,11 @@ class WindowsManifest(ViewerManifest): self.path("libvlccore.dll") self.path("plugins/") - # pull in the crash logger from other projects - # tag:"crash-logger" here as a cue to the exporter - self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], - dst="win_crash_logger.exe") + if not bugsplat_db: # don't include the win_crash_logger if we are using BugSplat + # pull in the crash logger from other projects + # tag:"crash-logger" here as a cue to the exporter + self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], + dst="win_crash_logger.exe") if not self.is_packaging_viewer(): self.package_file = "copied_deps" -- cgit v1.2.3 From 50509a56b6714a1a075463a02e5a853d97a3c461 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 25 Aug 2020 12:35:04 -0400 Subject: SL-10297 fix check for bugsplat --- indra/newview/viewer_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index c636f1d910..6161a8b413 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -673,7 +673,7 @@ class WindowsManifest(ViewerManifest): self.path("libvlccore.dll") self.path("plugins/") - if not bugsplat_db: # don't include the win_crash_logger if we are using BugSplat + if not self.args.get('bugsplat'): # don't include the win_crash_logger if we are using BugSplat # pull in the crash logger from other projects # tag:"crash-logger" here as a cue to the exporter self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], -- cgit v1.2.3 From 4e4564dcf31766469ccf41e0eef82bc234fda72c Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 26 Aug 2020 09:53:38 -0400 Subject: SL-10297 fix MSVC warning controls (merge error) --- indra/test/test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/test/test.cpp b/indra/test/test.cpp index b16fcb84d6..748d042631 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -58,7 +58,8 @@ #include #endif -#if LL_WINDOWS +#if LL_MSVC +#pragma warning (push) #pragma warning (disable : 4702) // warning C4702: unreachable code #endif #include -- cgit v1.2.3 From 1aa140d3affa28d85a41d55f2566a19fb9d2cff5 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 26 Aug 2020 15:33:20 -0400 Subject: SL-10297 fix MSVC unreachable code warning --- indra/test/test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra') diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 748d042631..55dad94bc1 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -77,8 +77,14 @@ LLError::ErrFatalHookResult wouldHaveCrashed(const std::string& message) { +#if LL_MSVC +#pragma warning (push) +#pragma warning (disable : 4702) // warning C4702: unreachable code tut::fail("fatal error message: " + message); return LLError::ERR_DO_NOT_CRASH; +#if LL_MSVC +#pragma warning (pop) +#endif } namespace tut -- cgit v1.2.3 From 6007475c87d3edbb023cc64bb097d33e6c04dfd4 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 26 Aug 2020 16:37:23 -0400 Subject: SL-10297 fix MSVC unreachable code warning (for real) --- indra/test/test.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 55dad94bc1..571f502861 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -80,6 +80,7 @@ LLError::ErrFatalHookResult wouldHaveCrashed(const std::string& message) #if LL_MSVC #pragma warning (push) #pragma warning (disable : 4702) // warning C4702: unreachable code +#endif tut::fail("fatal error message: " + message); return LLError::ERR_DO_NOT_CRASH; #if LL_MSVC -- cgit v1.2.3