diff options
| -rw-r--r-- | indra/llcommon/llerror.cpp | 8 | ||||
| -rw-r--r-- | indra/llcommon/llerror.h | 12 | ||||
| -rw-r--r-- | indra/llui/llnotifications.cpp | 8 | ||||
| -rw-r--r-- | indra/llui/lltransutil.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 103 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 27 | 
6 files changed, 131 insertions, 29 deletions
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 90c6ba309b..d834098994 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1604,11 +1604,11 @@ namespace LLError      std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning;      LLUserWarningMsg::Handler LLUserWarningMsg::sHandler; -    void LLUserWarningMsg::show(const std::string& message) +    void LLUserWarningMsg::show(const std::string& message, S32 error_code)      {          if (sHandler)          { -            sHandler(std::string(), message); +            sHandler(std::string(), message, error_code);          }      } @@ -1616,7 +1616,7 @@ namespace LLError      {          if (sHandler && !sLocalizedOutOfMemoryTitle.empty())          { -            sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning); +            sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning, ERROR_BAD_ALLOC);          }      } @@ -1627,7 +1627,7 @@ namespace LLError              "Second Life viewer couldn't access some of the files it needs and will be closed."              "\n\nPlease reinstall viewer from  https://secondlife.com/support/downloads/ and "              "contact https://support.secondlife.com if issue persists after reinstall."; -        sHandler("Missing Files", error_string); +        sHandler("Missing Files", error_string, ERROR_MISSING_FILES);      }      void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 8a143ff30a..87625b6ead 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -308,7 +308,15 @@ namespace LLError      class LLUserWarningMsg      {      public: -        typedef std::function<void(const std::string&, const std::string&)> Handler; +        typedef enum +        { +            ERROR_OTHER = 0, +            ERROR_BAD_ALLOC = 1, +            ERROR_MISSING_FILES = 2, +        } eLastExecEvent; + +        // tittle, message and error code to include in error marker file +        typedef std::function<void(const std::string&, const std::string&, S32 error_code)> Handler;          static void setHandler(const Handler&);          static void setOutOfMemoryStrings(const std::string& title, const std::string& message); @@ -316,7 +324,7 @@ namespace LLError          static void showOutOfMemory();          static void showMissingFiles();          // Genering error -        static void show(const std::string&); +        static void show(const std::string&, S32 error_code = -1);      private:          // needs to be preallocated before viewer runs out of memory diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index cd80e7f63f..7405413a3d 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1555,7 +1555,7 @@ bool LLNotifications::loadTemplates()          gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);      if (search_paths.empty())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL;      } @@ -1565,7 +1565,7 @@ bool LLNotifications::loadTemplates()      if (!success || root.isNull() || !root->hasName( "notifications" ))      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;          return false;      } @@ -1576,7 +1576,7 @@ bool LLNotifications::loadTemplates()      if(!params.validateBlock())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;          return false;      } @@ -1643,7 +1643,7 @@ bool LLNotifications::loadVisibilityRules()      if(!params.validateBlock())      { -        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); +        LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;          return false;      } diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 4af5376a8b..e82af0b96f 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -48,7 +48,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s              "Second Life viewer couldn't access some of the files it needs and will be closed."              "\n\nPlease reinstall viewer from  https://secondlife.com/support/downloads/ and "              "contact https://support.secondlife.com if issue persists after reinstall."; -        LLError::LLUserWarningMsg::show(error_string); +        LLError::LLUserWarningMsg::show(error_string, LLError::LLUserWarningMsg::ERROR_MISSING_FILES);          gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);          LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;          return false; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c770b7c917..d61c7da93e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2237,12 +2237,26 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)      }  } -void errorMSG(const std::string& title_string, const std::string& message_string) +void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)  {      if (!message_string.empty())      {          OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);      } +    switch (code) +    { +    case LLError::LLUserWarningMsg::ERROR_OTHER: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH); +        break; +    case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC); +        break; +    case LLError::LLUserWarningMsg::ERROR_MISSING_FILES: +        LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES); +        break; +    default: +        break; +    }  }  void LLAppViewer::initLoggingAndGetLastDuration() @@ -2256,7 +2270,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()      LLError::addGenericRecorder(&errorCallback);      //LLError::setTimeFunction(getRuntime); -    LLError::LLUserWarningMsg::setHandler(errorMSG); +    LLError::LLUserWarningMsg::setHandler(errorHandler);      if (mSecondInstance) @@ -3702,16 +3716,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const      bool sameVersion = false;      std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); -    char marker_version[MAX_MARKER_LENGTH]; +    char marker_data[MAX_MARKER_LENGTH];      S32  marker_version_length;      LLAPRFile marker_file;      marker_file.open(marker_name, LL_APR_RB);      if (marker_file.getFileHandle())      { -        marker_version_length = marker_file.read(marker_version, sizeof(marker_version)); -        std::string marker_string(marker_version, marker_version_length); -        if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) ) +        marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); +        std::string marker_string(marker_data, marker_version_length); +        size_t pos = marker_string.find('\n'); +        if (pos != std::string::npos) +        { +            marker_string = marker_string.substr(0, pos); +        } +        if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) )          {              sameVersion = true;          } @@ -3725,6 +3744,50 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const      return sameVersion;  } +S32 LLAppViewer::getMarkerData(const std::string& marker_name) const +{ +    bool sameVersion = false; + +    std::string my_version(LLVersionInfo::instance().getChannelAndVersion()); +    char marker_data[MAX_MARKER_LENGTH]; +    S32  marker_version_length; + +    LLAPRFile marker_file; +    marker_file.open(marker_name, LL_APR_RB); +    if (marker_file.getFileHandle()) +    { +        marker_version_length = marker_file.read(marker_data, sizeof(marker_data)); +        marker_file.close(); +        std::string marker_string(marker_data, marker_version_length); +        std::string data; +        size_t pos = marker_string.find('\n'); +        if (pos != std::string::npos) +        { +            data = marker_string.substr(pos + 1, marker_version_length - pos - 1); +            marker_string = marker_string.substr(0, pos); +        } +        if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length())) +        { +            sameVersion = true; +        } +        else +        { +            return -1; +        } +        LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': " +            << "\n   mine '" << my_version << "'" +            << "\n marker '" << marker_string << "'" +            << "\n " << (sameVersion ? "same" : "different") << " version" +            << LL_ENDL; +        if (data.length() == 0) +        { +            return 0; +        } +        return std::stoi(data); +    } +    return -1; +} +  void LLAppViewer::processMarkerFiles()  {      //We've got 4 things to test for here @@ -3859,17 +3922,23 @@ void LLAppViewer::processMarkerFiles()      std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);      if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))      { -        if (markerIsSameVersion(error_marker_file)) +        S32 marker_code = getMarkerData(error_marker_file); +        if (marker_code >= 0)          {              if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)              {                  gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;                  LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;              } +            else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT) +            { +                gLastExecEvent = (eLastExecEvent)marker_code; +                LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +            }              else              {                  gLastExecEvent = LAST_EXEC_OTHER_CRASH; -                LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; +                LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;              }          }          else @@ -5159,6 +5228,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)      gMainloopWork.post(work);  } +void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const +{ +    if (!mSecondInstance) +    { +        std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + +        LLAPRFile file; +        file.open(error_marker, LL_APR_WB); +        if (file.getFileHandle()) +        { +            recordMarkerVersion(file); +            std::string data = "\n" + std::to_string((S32)error_code); +            file.write(data.data(), static_cast<S32>(data.length())); +            file.close(); +        } +    } +} +  void LLAppViewer::outOfMemorySoftQuit()  {      if (!mQuitRequested) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 4ce4259ed8..31acb0ae85 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -66,6 +66,19 @@ class LLViewerRegion;  extern LLTrace::BlockTimerStatHandle FTM_FRAME; +typedef enum +{ +    LAST_EXEC_NORMAL = 0, +    LAST_EXEC_FROZE, +    LAST_EXEC_LLERROR_CRASH, +    LAST_EXEC_OTHER_CRASH, +    LAST_EXEC_LOGOUT_FROZE, +    LAST_EXEC_LOGOUT_CRASH, +    LAST_EXEC_BAD_ALLOC, +    LAST_EXEC_MISSING_FILES, +    LAST_EXEC_COUNT +} eLastExecEvent; +  class LLAppViewer : public LLApp  {  public: @@ -227,6 +240,9 @@ public:      // post given work to the "mainloop" work queue for handling on the main thread      void postToMainCoro(const LL::WorkQueue::Work& work); +    // Writes an error code into the error_marker file for use on next startup. +    void createErrorMarker(eLastExecEvent error_code) const; +      // Attempt a 'soft' quit with disconnect and saving of settings/cache.      // Intended to be thread safe.      // Good chance of viewer crashing either way, but better than alternatives. @@ -272,6 +288,7 @@ private:      void processMarkerFiles();      static void recordMarkerVersion(LLAPRFile& marker_file);      bool markerIsSameVersion(const std::string& marker_name) const; +    S32 getMarkerData(const std::string& marker_name) const;      void idle();      void idleShutdown(); @@ -347,16 +364,6 @@ private:  extern LLSD gDebugInfo;  extern bool gShowObjectUpdates; -typedef enum -{ -    LAST_EXEC_NORMAL = 0, -    LAST_EXEC_FROZE, -    LAST_EXEC_LLERROR_CRASH, -    LAST_EXEC_OTHER_CRASH, -    LAST_EXEC_LOGOUT_FROZE, -    LAST_EXEC_LOGOUT_CRASH -} eLastExecEvent; -  extern eLastExecEvent gLastExecEvent; // llstartup  extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown)  | 
