summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-11-14 23:33:13 +0200
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2025-01-22 16:06:30 +0200
commitad375d611648cb36c5949a9569b48a87289ab6db (patch)
tree73cd8e1df5fcb9cec958ecab63b337be9ece5521
parent9159922bdf47093ba2330ce38ea69562fbbaedb1 (diff)
viewer#3088 Report out of memory as a separate 'category'
-rw-r--r--indra/llcommon/llerror.cpp8
-rw-r--r--indra/llcommon/llerror.h12
-rw-r--r--indra/llui/llnotifications.cpp8
-rw-r--r--indra/llui/lltransutil.cpp2
-rw-r--r--indra/newview/llappviewer.cpp103
-rw-r--r--indra/newview/llappviewer.h27
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)