diff options
-rwxr-xr-x | indra/llcrashlogger/llcrashlogger.cpp | 88 | ||||
-rwxr-xr-x | indra/llcrashlogger/llcrashlogger.h | 1 | ||||
-rw-r--r-- | indra/mac_crash_logger/llcrashloggermac.cpp | 83 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 30 |
4 files changed, 87 insertions, 115 deletions
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 078795f962..a91cf530b5 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 |