diff options
author | Mnikolenko Productengine <mnikolenko@productengine.com> | 2021-05-26 14:57:31 +0300 |
---|---|---|
committer | Mnikolenko Productengine <mnikolenko@productengine.com> | 2021-05-26 14:57:31 +0300 |
commit | 74711a2cf263a131799bd29f566c6929377617d3 (patch) | |
tree | 1adfb788a91c9ea58f63bb1cb535ec8b63b72bf2 /indra | |
parent | 8e862032d1fb0a75dfc07de1f674fb61422b9f37 (diff) |
SL-15196 Attach correct log file to Bugsplat report
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llvfs/lldir.cpp | 5 | ||||
-rw-r--r-- | indra/llvfs/lldir.h | 2 | ||||
-rw-r--r-- | indra/llwindow/llappdelegate-objc.h | 1 | ||||
-rw-r--r-- | indra/newview/llappdelegate-objc.mm | 12 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 170 | ||||
-rw-r--r-- | indra/newview/llappviewermacosx-for-objc.h | 2 | ||||
-rw-r--r-- | indra/newview/llappviewermacosx.cpp | 28 | ||||
-rw-r--r-- | indra/newview/llappviewerwin32.cpp | 2 |
8 files changed, 151 insertions, 71 deletions
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 10fbc06c61..18a1bcb1be 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -891,6 +891,11 @@ std::string LLDir::getScrubbedFileName(const std::string uncleanFileName) return name; } +std::string LLDir::getDumpLogsDirPath(const std::string &file_name) +{ + return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "dump_logs", file_name); +} + // static std::string LLDir::getForbiddenFileChars() { diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 38e204ef04..bf01d31d86 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -179,6 +179,8 @@ class LLDir // random filename in common temporary directory std::string getTempFilename() const; + static std::string getDumpLogsDirPath(const std::string &file_name = ""); + // For producing safe download file names from potentially unsafe ones static std::string getScrubbedFileName(const std::string uncleanFileName); static std::string getForbiddenFileChars(); diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h index 0b38647b4a..ceda7ff74c 100644 --- a/indra/llwindow/llappdelegate-objc.h +++ b/indra/llwindow/llappdelegate-objc.h @@ -33,6 +33,7 @@ LLNonInlineTextView *inputView; NSTimer *frameTimer; NSString *currentInputLanguage; + std::string secondLogPath; } @property (assign) IBOutlet LLNSWindow *window; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 3f1b5139c5..8063d7fda3 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -299,6 +299,12 @@ struct AttachmentInfo AttachmentInfo(metadata.staticDebugPathname, "text/xml") }; + secondLogPath = metadata.secondLogFilePathname; + if(!secondLogPath.empty()) + { + info.push_back(AttachmentInfo(secondLogPath, "text/xml")); + } + // 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. @@ -333,6 +339,12 @@ struct AttachmentInfo - (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager { infos("Sent crash report to BugSplat"); + + if(!secondLogPath.empty()) + { + boost::filesystem::remove(secondLogPath); + } + clearDumpLogsDir(); } - (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 208204e085..bd859ca23f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -715,8 +715,6 @@ LLAppViewer::LLAppViewer() gLoggedInTime.stop(); - initLoggingAndGetLastDuration(); - processMarkerFiles(); // // OK to write stuff to logs now, we've now crash reported if necessary @@ -1303,6 +1301,13 @@ bool LLAppViewer::init() // Load User's bindings loadKeyBindings(); +#if LL_WINDOWS + if (!mSecondInstance) + { + gDirUtilp->deleteDirAndContents(gDirUtilp->getDumpLogsDirPath()); + } +#endif + return true; } @@ -2264,75 +2269,87 @@ void errorCallback(const std::string &error_string) void LLAppViewer::initLoggingAndGetLastDuration() { - // - // Set up logging defaults for the viewer - // - LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "") + // + // Set up logging defaults for the viewer + // + 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, - "SecondLife.old"); - LLFile::remove(old_log_file); - - // Get name of the log file - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "SecondLife.log"); - /* - * Before touching any log files, compute the duration of the last run - * by comparing the ctime of the previous start marker file with the ctime - * of the last log file. - */ - std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME); - llstat start_marker_stat; - llstat log_file_stat; - std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below - int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat); - int log_stat_result = LLFile::stat(log_file, &log_file_stat); - if ( 0 == start_stat_result && 0 == log_stat_result ) - { - int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime; - // only report a last run time if the last viewer was the same version - // because this stat will be counted against this version - if ( markerIsSameVersion(start_marker_file_name) ) - { - gLastExecDuration = elapsed_seconds; - } - else - { - duration_log_stream << "start marker from some other version; duration is not reported"; - gLastExecDuration = -1; - } - } - else - { - // at least one of the LLFile::stat calls failed, so we can't compute the run time - duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result; - gLastExecDuration = -1; // unknown - } - std::string duration_log_msg(duration_log_stream.str()); + LLError::setFatalFunction(errorCallback); + //LLError::setTimeFunction(getRuntime); - // Create a new start marker file for comparison with log file time for the next run - LLAPRFile start_marker_file ; - start_marker_file.open(start_marker_file_name, LL_APR_WB); - if (start_marker_file.getFileHandle()) - { - recordMarkerVersion(start_marker_file); - start_marker_file.close(); - } - // Rename current log file to ".old" - LLFile::rename(log_file, old_log_file); + if (mSecondInstance) + { + LLFile::mkdir(gDirUtilp->getDumpLogsDirPath()); + + LLUUID uid; + uid.generate(); + LLError::logToFile(gDirUtilp->getDumpLogsDirPath(uid.asString() + ".log")); + } + else + { + // Remove the last ".old" log file. + std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + "SecondLife.old"); + LLFile::remove(old_log_file); + + // Get name of the log file + std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + "SecondLife.log"); + /* + * Before touching any log files, compute the duration of the last run + * by comparing the ctime of the previous start marker file with the ctime + * of the last log file. + */ + std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME); + llstat start_marker_stat; + llstat log_file_stat; + std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below + int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat); + int log_stat_result = LLFile::stat(log_file, &log_file_stat); + if (0 == start_stat_result && 0 == log_stat_result) + { + int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime; + // only report a last run time if the last viewer was the same version + // because this stat will be counted against this version + if (markerIsSameVersion(start_marker_file_name)) + { + gLastExecDuration = elapsed_seconds; + } + else + { + duration_log_stream << "start marker from some other version; duration is not reported"; + gLastExecDuration = -1; + } + } + else + { + // at least one of the LLFile::stat calls failed, so we can't compute the run time + duration_log_stream << "duration stat failure; start: " << start_stat_result << " log: " << log_stat_result; + gLastExecDuration = -1; // unknown + } + std::string duration_log_msg(duration_log_stream.str()); - // Set the log file to SecondLife.log - LLError::logToFile(log_file); - if (!duration_log_msg.empty()) - { - LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; - } + // Create a new start marker file for comparison with log file time for the next run + LLAPRFile start_marker_file; + start_marker_file.open(start_marker_file_name, LL_APR_WB); + if (start_marker_file.getFileHandle()) + { + recordMarkerVersion(start_marker_file); + start_marker_file.close(); + } + + // Rename current log file to ".old" + LLFile::rename(log_file, old_log_file); + + // Set the log file to SecondLife.log + LLError::logToFile(log_file); + if (!duration_log_msg.empty()) + { + LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL; + } + } } bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, @@ -3776,6 +3793,7 @@ void LLAppViewer::processMarkerFiles() // - Other Crash (SecondLife.error_marker present) // These checks should also remove these files for the last 2 cases if they currently exist + std::ostringstream marker_log_stream; bool marker_is_same_version = true; // first, look for the marker created at startup and deleted on a clean exit mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); @@ -3786,12 +3804,12 @@ void LLAppViewer::processMarkerFiles() marker_is_same_version = markerIsSameVersion(mMarkerFileName); // now test to see if this file is locked by a running process (try to open for write) - LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL; + marker_log_stream << "Checking exec marker file for lock..."; mMarkerFile.open(mMarkerFileName, LL_APR_WB); apr_file_t* fMarker = mMarkerFile.getFileHandle() ; if (!fMarker) { - LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL; + marker_log_stream << "Exec marker file open failed - assume it is locked."; mSecondInstance = true; // lock means that instance is running. } else @@ -3799,16 +3817,20 @@ void LLAppViewer::processMarkerFiles() // We were able to open it, now try to lock it ourselves... if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) { - LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL; + marker_log_stream << "Locking exec marker failed."; mSecondInstance = true; // lost a race? be conservative } else { // No other instances; we've locked this file now, so record our version; delete on quit. recordMarkerVersion(mMarkerFile); - LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL; + marker_log_stream << "Exec marker file existed but was not locked; rewritten."; } } + initLoggingAndGetLastDuration(); + + std::string marker_log_msg(marker_log_stream.str()); + LL_INFOS("MarkerFile") << marker_log_msg << LL_ENDL; if (mSecondInstance) { @@ -3828,6 +3850,7 @@ void LLAppViewer::processMarkerFiles() } else // marker did not exist... last exec (if any) did not freeze { + initLoggingAndGetLastDuration(); // Create the marker file for this execution & lock it; it will be deleted on a clean exit apr_status_t s; s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE); @@ -3955,6 +3978,13 @@ void LLAppViewer::removeDumpDir() //its locking table for us. std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); gDirUtilp->deleteDirAndContents(dump_dir); + + if (mSecondInstance && !isError()) + { + std::string log_filename = LLError::logFileName(); + LLError::logToFile(""); + LLFile::remove(log_filename); + } } void LLAppViewer::forceQuit() diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h index 79c3efff91..94bfa2491b 100644 --- a/indra/newview/llappviewermacosx-for-objc.h +++ b/indra/newview/llappviewermacosx-for-objc.h @@ -31,6 +31,7 @@ bool pumpMainLoop(); void handleQuit(); void cleanupViewer(); void infos(const std::string& message); +void clearDumpLogsDir(); // This struct is malleable; it only serves as a way to convey a number of // fields from llappviewermacosx.cpp's CrashMetadata_instance() function to the @@ -47,6 +48,7 @@ struct CrashMetadata std::string agentFullname; std::string regionName; std::string fatalMessage; + std::string secondLogFilePathname; }; CrashMetadata& CrashMetadata_instance(); diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 662164af2d..75ce26fb18 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -57,6 +57,7 @@ #include <fstream> #include "lldir.h" +#include "lldiriterator.h" #include <signal.h> #include <CoreAudio/CoreAudio.h> // for systemwide mute class LLMediaCtrl; // for LLURLDispatcher @@ -154,6 +155,14 @@ void cleanupViewer() gViewerAppPtr = NULL; } +void clearDumpLogsDir() +{ + if (!LLAppViewer::instance()->isSecondInstance()) + { + gDirUtilp->deleteDirAndContents(gDirUtilp->getDumpLogsDirPath()); + } +} + // The BugsplatMac API is structured as a number of different method // overrides, each returning a different piece of metadata. But since we // obtain such metadata by opening and parsing a file, it seems ridiculous to @@ -199,6 +208,7 @@ CrashMetadataSingleton::CrashMetadataSingleton() else { LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL; + logFilePathname = get_metadata(info, "SLLog"); userSettingsPathname = get_metadata(info, "SettingsFilename"); accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename"); @@ -208,6 +218,24 @@ CrashMetadataSingleton::CrashMetadataSingleton() LLStringUtil::replaceChar(agentFullname, '_', ' '); regionName = get_metadata(info, "CurrentRegion"); fatalMessage = get_metadata(info, "FatalMessage"); + + if (gDirUtilp->fileExists(gDirUtilp->getDumpLogsDirPath())) + { + LLDirIterator file_iter(gDirUtilp->getDumpLogsDirPath(), "*.log"); + std::string file_name; + bool found = true; + while(found) + { + if((found = file_iter.next(file_name))) + { + std::string log_filename = gDirUtilp->getDumpLogsDirPath(file_name); + if(LLError::logFileName() != log_filename) + { + secondLogFilePathname = log_filename; + } + } + } + } } } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 9b1c0d1f8b..60fcad07f1 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -121,7 +121,7 @@ namespace // send the main viewer log file // widen to wstring, convert to __wchar_t, then pass c_str() sBugSplatSender->sendAdditionalFile( - WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))); + WCSTR(LLError::logFileName())); sBugSplatSender->sendAdditionalFile( WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml"))); |