summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrew A. de Laix <alain@lindenlab.com>2010-06-03 14:57:04 -0700
committerAndrew A. de Laix <alain@lindenlab.com>2010-06-03 14:57:04 -0700
commit6b9442a88da27181b2692528ff74e0d0c0985cdd (patch)
treea1b1c9cc282309475729581b26371264e40d6376 /indra
parent792b9d38cbf5fc5d03339c255a13912fa85bee51 (diff)
parentf9468db62e848b9d5d3aae54355e522bd6be10e4 (diff)
Automated merge with ssh://hg.lindenlab.com/brad/viewer-public
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.cpp88
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.h1
-rw-r--r--indra/mac_crash_logger/llcrashloggermac.cpp83
-rw-r--r--indra/newview/llappviewer.cpp30
4 files changed, 87 insertions, 115 deletions
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 51e5f14bfe..89ebf0eccb 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -36,6 +36,8 @@
#include "llcrashlogger.h"
#include "linden_common.h"
+#include "lldate.h"
+#include "llfile.h"
#include "llstring.h"
#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
#include "llerror.h"
@@ -153,54 +155,79 @@ std::string getStartupStateFromLog(std::string& sllog)
return startup_state;
}
-void LLCrashLogger::gatherFiles()
+void LLCrashLogger::findAndRenameLogFiles()
{
- updateApplication("Gathering logs...");
+ // Find and rename the relevant log files so they won't be stomped on if
+ // SL is restarted before user sends crash report.
+
+ std::string now = "." + LLDate::now().asString();
+
+ std::string stats_log_original = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
+ std::string stats_log = stats_log_original;
+ stats_log.insert(stats_log.length() - 4, now);
+ if(LLFile::rename(stats_log_original, stats_log) == 0)
+ {
+ mFileMap["StatsLog"] = stats_log;
+ }
+
+ std::string second_life_log_original;
+ std::string settings_file_original;
- // Figure out the filename of the debug log
- std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
+ std::string db_file_name_original = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
+ std::string db_file_name = db_file_name_original;
+ db_file_name.insert(db_file_name.length() - 4, now);
+ LLFile::rename(db_file_name_original, db_file_name);
std::ifstream debug_log_file(db_file_name.c_str());
-
- // Look for it in the debug_info.log file
if (debug_log_file.is_open())
{
- LLSDSerialize::fromXML(mDebugLog, debug_log_file);
-
+ LLSDSerialize::fromXML(mDebugLog, debug_log_file);
mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
-
- mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString();
- mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString();
- if(mDebugLog.has("CAFilename"))
- {
- LLCurl::setCAFile(mDebugLog["CAFilename"].asString());
- }
- else
- {
- LLCurl::setCAFile(gDirUtilp->getCAFile());
- }
-
- llinfos << "Using log file from debug log " << mFileMap["SecondLifeLog"] << llendl;
- llinfos << "Using settings file from debug log " << mFileMap["SettingsXml"] << llendl;
+ second_life_log_original = mDebugLog["SLLog"].asString();
+ settings_file_original = mDebugLog["SettingsFilename"].asString();
}
else
{
// Figure out the filename of the second life log
- LLCurl::setCAFile(gDirUtilp->getCAFile());
- mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
- mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
+ second_life_log_original = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
+ settings_file_original = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
}
-
+
if(mCrashInPreviousExec)
{
// Restarting after freeze.
// Replace the log file ext with .old, since the
// instance that launched this process has overwritten
// SecondLife.log
- std::string log_filename = mFileMap["SecondLifeLog"];
- log_filename.replace(log_filename.size() - 4, 4, ".old");
- mFileMap["SecondLifeLog"] = log_filename;
+ second_life_log_original.replace(second_life_log_original.size() - 4, 4, ".old");
}
+
+ std::string second_life_log = second_life_log_original;
+ std::string settings_file = settings_file_original;
+ second_life_log.insert(second_life_log.length() - 4, now);
+ settings_file.insert(settings_file.length() - 4, now);
+ if(LLFile::rename(second_life_log_original, second_life_log) == 0)
+ {
+ mFileMap["SecondLifeLog"] = second_life_log;
+ }
+ if(LLFile::rename(settings_file_original, settings_file) == 0)
+ {
+ mFileMap["SettingsXml"] = settings_file;
+ }
+}
+
+void LLCrashLogger::gatherFiles()
+{
+ updateApplication("Gathering logs...");
+ if(mDebugLog.has("CAFilename"))
+ {
+ LLCurl::setCAFile(mDebugLog["CAFilename"].asString());
+ }
+ else
+ {
+ LLCurl::setCAFile(gDirUtilp->getCAFile());
+ }
+
gatherPlatformSpecificFiles();
//Use the debug log to reconstruct the URL to send the crash report to
@@ -230,7 +257,6 @@ void LLCrashLogger::gatherFiles()
mAltCrashHost = "https://login.agni.lindenlab.com:12043/crash/report";
mCrashInfo["DebugLog"] = mDebugLog;
- mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
updateApplication("Encoding files...");
@@ -405,5 +431,7 @@ bool LLCrashLogger::init()
LLAPRFile::remove( marker_file );
}
+ findAndRenameLogFiles();
+
return true;
}
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
index f8abe20597..a3cb17a958 100755
--- a/indra/llcrashlogger/llcrashlogger.h
+++ b/indra/llcrashlogger/llcrashlogger.h
@@ -48,6 +48,7 @@ public:
S32 loadCrashBehaviorSetting();
void gatherFiles();
virtual void gatherPlatformSpecificFiles() {}
+ void findAndRenameLogFiles();
bool saveCrashBehaviorSetting(S32 crash_behavior);
bool sendCrashLogs();
LLSD constructPostData();
diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp
index 16efa4fe2c..90de39ba27 100644
--- a/indra/mac_crash_logger/llcrashloggermac.cpp
+++ b/indra/mac_crash_logger/llcrashloggermac.cpp
@@ -211,89 +211,6 @@ bool LLCrashLoggerMac::init(void)
void LLCrashLoggerMac::gatherPlatformSpecificFiles()
{
updateApplication("Gathering hardware information...");
- char path[MAX_PATH];
- FSRef folder;
-
- if(FSFindFolder(kUserDomain, kLogsFolderType, false, &folder) == noErr)
- {
- // folder is an FSRef to ~/Library/Logs/
- if(FSRefMakePath(&folder, (UInt8*)&path, sizeof(path)) == noErr)
- {
- struct stat dw_stat;
- std::string mBuf;
- bool isLeopard = false;
- // Try the 10.3 path first...
- std::string dw_file_name = std::string(path) + std::string("/CrashReporter/Second Life.crash.log");
- int res = stat(dw_file_name.c_str(), &dw_stat);
-
- if (res)
- {
- // Try the 10.2 one next...
- dw_file_name = std::string(path) + std::string("/Second Life.crash.log");
- res = stat(dw_file_name.c_str(), &dw_stat);
- }
-
- if(res)
- {
- //10.5: Like 10.3+, except it puts the crash time in the file instead of dividing it up
- //using asterisks. Get a directory listing, search for files starting with second life,
- //use the last one found.
- std::string old_file_name, current_file_name, pathname, mask;
- pathname = std::string(path) + std::string("/CrashReporter/");
- mask = "Second Life*";
- while(gDirUtilp->getNextFileInDir(pathname, mask, current_file_name, false))
- {
- old_file_name = current_file_name;
- }
- if(old_file_name != "")
- {
- dw_file_name = pathname + old_file_name;
- res=stat(dw_file_name.c_str(), &dw_stat);
- isLeopard = true;
- }
- }
-
- if (!res)
- {
- std::ifstream fp(dw_file_name.c_str());
- std::stringstream str;
- if(!fp.is_open()) return;
- str << fp.rdbuf();
- mBuf = str.str();
-
- if(!isLeopard)
- {
- // Crash logs consist of a number of entries, one per crash.
- // Each entry is preceeded by "**********" on a line by itself.
- // We want only the most recent (i.e. last) one.
- const char *sep = "**********";
- const char *start = mBuf.c_str();
- const char *cur = start;
- const char *temp = strstr(cur, sep);
-
- while(temp != NULL)
- {
- // Skip past the marker we just found
- cur = temp + strlen(sep); /* Flawfinder: ignore */
-
- // and try to find another
- temp = strstr(cur, sep);
- }
-
- // If there's more than one entry in the log file, strip all but the last one.
- if(cur != start)
- {
- mBuf.erase(0, cur - start);
- }
- }
- mCrashInfo["CrashLog"] = mBuf;
- }
- else
- {
- llwarns << "Couldn't find any CrashReporter files..." << llendl;
- }
- }
- }
}
bool LLCrashLoggerMac::mainLoop()
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 351c0cbae5..a5343bb522 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -81,7 +81,7 @@
#include "llvoicechannel.h"
#include "llvoavatarself.h"
#include "llsidetray.h"
-
+#include "lldate.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
@@ -102,6 +102,7 @@
// Third party library includes
#include <boost/bind.hpp>
+#include <boost/regex.hpp>
#if LL_WINDOWS
@@ -1242,12 +1243,37 @@ bool LLAppViewer::cleanup()
// workaround for DEV-35406 crash on shutdown
LLEventPumps::instance().reset();
- // remove any old breakpad minidump files from the log directory
if (! isError())
{
+ // remove any old breakpad minidump files from the log directory
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
logdir += gDirUtilp->getDirDelimiter();
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
+
+ // remove any old log files saved from old crash reports.
+ const static std::string mask = "*.*.log";
+ std::string filename;
+ while (gDirUtilp->getNextFileInDir(logdir, mask, filename, false))
+ {
+ static const boost::regex
+ file_regex(".*\\.(.*)\\.log", boost::regex::extended);
+ boost::smatch match;
+ if(boost::regex_match(filename, match, file_regex) && match.size() > 1)
+ {
+ F64 date = LLDate(match[1]).secondsSinceEpoch();
+ F64 age = LLDate::now().secondsSinceEpoch() - date;
+ if( date > 0.0 && age > 604800.0 )
+ {
+ // Clean up files older than 1 week.
+ llinfos << "removing old log file " << filename << llendl;
+ LLFile::remove(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename));
+ }
+ }
+ else
+ {
+ // ignore;
+ }
+ }
}
// *TODO - generalize this and move DSO wrangling to a helper class -brad