diff options
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"))); | 
