diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llerror.cpp | 33 | ||||
| -rw-r--r-- | indra/llcommon/llerrorcontrol.h | 3 | ||||
| -rw-r--r-- | indra/newview/llappdelegate-objc.mm | 34 | ||||
| -rw-r--r-- | indra/newview/llappviewermacosx-for-objc.h | 2 | ||||
| -rw-r--r-- | indra/newview/llappviewermacosx.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llappviewerwin32.cpp | 53 | 
6 files changed, 101 insertions, 36 deletions
| diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f31a054139..b5e7e81f21 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -377,6 +377,7 @@ namespace  	public:  		std::ostringstream messageStream;  		bool messageStreamInUse; +		std::string mFatalMessage;  		void addCallSite(LLError::CallSite&);  		void invalidateCallSites(); @@ -670,11 +671,16 @@ namespace LLError  		s->mCrashFunction = f;  	} -    FatalFunction getFatalFunction() -    { +	FatalFunction getFatalFunction() +	{  		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -        return s->mCrashFunction; -    } +		return s->mCrashFunction; +	} + +	std::string getFatalMessage() +	{ +		return Globals::getInstance()->mFatalMessage; +	}  	void setTimeFunction(TimeFunction f)  	{ @@ -1194,7 +1200,7 @@ namespace LLError  		{  			writeToRecorders(site, "error", true, true, true, false, false);  		} -		 +  		std::ostringstream message_stream;  		if (site.mPrintOnce) @@ -1219,14 +1225,19 @@ namespace LLError  				s->mUniqueLogMessages[message] = 1;  			}  		} -		 +  		message_stream << message; -		 -		writeToRecorders(site, message_stream.str()); -		 -		if (site.mLevel == LEVEL_ERROR  &&  s->mCrashFunction) +		std::string message_line(message_stream.str()); + +		writeToRecorders(site, message_line); + +		if (site.mLevel == LEVEL_ERROR)  		{ -			s->mCrashFunction(message_stream.str()); +			g->mFatalMessage = message_line; +			if (s->mCrashFunction) +			{ +				s->mCrashFunction(message_line); +			}  		}  	}  } diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index caf2ba72c2..ddbcdc94a0 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -102,6 +102,9 @@ namespace LLError  	LL_COMMON_API FatalFunction getFatalFunction();  		// Retrieve the previously-set FatalFunction +	LL_COMMON_API std::string getFatalMessage(); +		// Retrieve the message last passed to FatalFunction, if any +  	/// temporarily override the FatalFunction for the duration of a  	/// particular scope, e.g. for unit tests  	class LL_COMMON_API OverrideFatalFunction diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 4510f4070f..82e49540a4 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -74,9 +74,9 @@  #if defined(LL_BUGSPLAT)  	// https://www.bugsplat.com/docs/platforms/os-x#initialization -//	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; -//	[BugsplatStartupManager sharedManager].askUserDetails = NO; -    [BugsplatStartupManager sharedManager].delegate = self; +	[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; +	[BugsplatStartupManager sharedManager].askUserDetails = NO; +	[BugsplatStartupManager sharedManager].delegate = self;  	[[BugsplatStartupManager sharedManager] start];  #endif  } @@ -196,17 +196,20 @@  #if defined(LL_BUGSPLAT) -#if 0 -// Apparently this override method only contributes the User Description field -// of BugSplat's All Crashes table. Despite the method name, it would seem to -// be a bad place to try to stuff all of SecondLife.log.  - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager  { -//  return NSStringFromSelector(_cmd);      infos("Reached applicationLogForBugsplatStartupManager"); -    return @"[contents of SecondLife.log]"; +    // Apparently this override method only contributes the User Description +    // field of BugSplat's All Crashes table. Despite the method name, it +    // would seem to be a bad place to try to stuff all of SecondLife.log. +    return [NSString stringWithCString:getFatalMessage().c_str() +                              encoding:NSUTF8StringEncoding]; +} + +- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager +{ +    infos("Reached bugsplatStartupManagerWillSendCrashReport");  } -#endif  - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {      // We get the *old* log file pathname (for SecondLife.old) because it's on @@ -228,6 +231,17 @@      return attachment;  } +- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager +{ +    infos("Sent crash report to BugSplat"); +} + +- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error +{ +    // TODO: message string from NSError +    infos("Could not send crash report to BugSplat"); +} +  #endif // LL_BUGSPLAT  @end diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h index c439297611..ac85d7e8c3 100644 --- a/indra/newview/llappviewermacosx-for-objc.h +++ b/indra/newview/llappviewermacosx-for-objc.h @@ -30,6 +30,8 @@ bool pumpMainLoop();  void handleQuit();  void cleanupViewer();  std::string getOldLogFilePathname(); +std::string getFatalMessage(); +std::string getAgentFullname();  void infos(const std::string& message);  #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */ diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index d014e992f9..c3a3c3284a 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -45,6 +45,8 @@  #include "llmd5.h"  #include "llfloaterworldmap.h"  #include "llurldispatcher.h" +#include "llerrorcontrol.h" +#include "llvoavatarself.h"         // for gAgentAvatarp->getFullname()  #include <ApplicationServices/ApplicationServices.h>  #ifdef LL_CARBON_CRASH_HANDLER  #include <Carbon/Carbon.h> @@ -153,6 +155,16 @@ std::string getOldLogFilePathname()      return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");  } +std::string getFatalMessage() +{ +    return LLError::getFatalMessage(); +} + +std::string getAgentFullname() +{ +    return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string(); +} +  void infos(const std::string& message)  {      LL_INFOS() << message << LL_ENDL; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 247b94db3e..1e135fa229 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -67,6 +67,7 @@  #include "stringize.h"  #include "lldir.h" +#include "llerrorcontrol.h"  #include <fstream>  #include <exception> @@ -74,7 +75,10 @@  // Bugsplat (http://bugsplat.com) crash reporting tool  #ifdef LL_BUGSPLAT  #include "BugSplat.h" -#include "reader.h" // JsonCpp +#include "reader.h"                 // JsonCpp +#include "llagent.h"                // for agent location +#include "llviewerregion.h" +#include "llvoavatarself.h"         // for agent name  namespace  { @@ -85,7 +89,8 @@ namespace      // std::basic_string instance will survive until the function returns.      // Calling c_str() on a std::basic_string local to wunder() would be      // Undefined Behavior: we'd be left with a pointer into a destroyed -    // std::basic_string instance. +    // std::basic_string instance. But we can do that with a macro... +    #define WCSTR(string) wunder(string).c_str()      // It would be nice if, when wchar_t is the same as __wchar_t, this whole      // function would optimize away. However, we use it only for the arguments @@ -111,19 +116,35 @@ namespace      bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)      { -        // If we haven't yet initialized LLDir, don't bother trying to -        // find our log file. -        // Alternatively -- if we might encounter trouble trying to query -        // LLDir during crash cleanup -- consider making gDirUtilp an -        // LLPounceable, and attach a callback that stores the pathname to -        // the log file here. -        if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp) +        if (nCode == MDSCB_EXCEPTIONCODE)          {              // send the main viewer log file              // widen to wstring, convert to __wchar_t, then pass c_str()              sBugSplatSender->sendAdditionalFile( -                wunder(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str()); -        } +                WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))); + +            if (gAgentAvatarp) +            { +                // user name, when we have it +                sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname())); +            } + +            // LL_ERRS message, when there is one +            sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage())); + +            if (gAgent.getRegion()) +            { +                // region location, when we have it +                LLVector3 loc = gAgent.getPositionAgent(); +                sBugSplatSender->resetAppIdentifier( +                    WCSTR(STRINGIZE(gAgent.getRegion()->getName() +                                    << '/' << loc.mV[0] +                                    << '/' << loc.mV[1] +                                    << '/' << loc.mV[2]))); +            } + +            LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL; +        } // MDSCB_EXCEPTIONCODE          return false;      } @@ -603,10 +624,12 @@ bool LLAppViewerWin32::init()  				// have to convert normal wide strings to strings of __wchar_t  				sBugSplatSender = new MiniDmpSender( -					wunder(BugSplat_DB.asString()).c_str(), -					wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(), -					wunder(version_string).c_str(), -					nullptr); +					WCSTR(BugSplat_DB.asString()), +					WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)), +					WCSTR(version_string), +					nullptr,              // szAppIdentifier -- set later +					MDSF_NONINTERACTIVE | // automatically submit report without prompting +					MDSF_PREVENTHIJACKING); // disallow swiping Exception filter  				sBugSplatSender->setCallback(bugsplatSendLog);  				// engage stringize() overload that converts from wstring | 
