maint-5422 changes and merge from release

master
Glenn Glazer 2015-09-16 14:21:03 -07:00
parent 1be6320933
commit b09f0a120e
5 changed files with 84 additions and 116 deletions

View File

@ -39,12 +39,14 @@
#include "lltimer.h"
#include "lldir.h"
#include "llfile.h"
#include "llsdserialize.h"
#include "lliopipe.h"
#include "llpumpio.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llproxy.h"
#include "llsdutil.h" //remove
#include <boost/regex.hpp>
LLPumpIO* gServicePump = NULL;
BOOL gBreak = false;
@ -140,16 +142,16 @@ std::string getStartupStateFromLog(std::string& sllog)
return startup_state;
}
bool LLCrashLogger::readDebugFromXML(LLSD& dest, const std::string& filename )
bool LLCrashLogger::readFromXML(LLSD& dest, const std::string& filename )
{
std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,filename);
std::ifstream debug_log_file(db_file_name.c_str());
std::ifstream log_file(db_file_name.c_str());
// Look for it in the debug_info.log file
if (debug_log_file.is_open())
// Look for it in the given file
if (log_file.is_open())
{
LLSDSerialize::fromXML(dest, debug_log_file);
debug_log_file.close();
LLSDSerialize::fromXML(dest, log_file);
log_file.close();
return true;
}
return false;
@ -193,9 +195,18 @@ void LLCrashLogger::gatherFiles()
LLSD static_sd;
LLSD dynamic_sd;
//if we ever want to change the endpoint we send crashes to
//we can construct a file download ( a la feature table filename for example)
//containing the new endpoint
LLSD endpoint;
std::string grid;
std::string fqdn;
bool has_logs = readDebugFromXML( static_sd, "static_debug_info.log" );
has_logs |= readDebugFromXML( dynamic_sd, "dynamic_debug_info.log" );
bool has_logs = readFromXML( static_sd, "static_debug_info.log" );
has_logs |= readFromXML( dynamic_sd, "dynamic_debug_info.log" );
bool has_endpoint = readFromXML( endpoint, "endpoint.xml" );
if ( has_logs )
{
@ -233,31 +244,41 @@ void LLCrashLogger::gatherFiles()
gatherPlatformSpecificFiles();
//Use the debug log to reconstruct the URL to send the crash report to
if(mDebugLog.has("CrashHostUrl"))
{
// Crash log receiver has been manually configured.
mCrashHost = mDebugLog["CrashHostUrl"].asString();
}
else if(mDebugLog.has("CurrentSimHost"))
{
mCrashHost = "https://";
mCrashHost += mDebugLog["CurrentSimHost"].asString();
mCrashHost += ":12043/crash/report";
}
else if(mDebugLog.has("GridName"))
{
// This is a 'little' hacky, but its the best simple solution.
std::string grid_host = mDebugLog["GridName"].asString();
LLStringUtil::toLower(grid_host);
mCrashHost = "https://login.";
mCrashHost += grid_host;
mCrashHost += ".lindenlab.com:12043/crash/report";
}
if ( has_endpoint && endpoint.has("ViewerCrashReceiver" ) )
{
mCrashHost = endpoint["ViewerCrashReceiver"].asString();
}
else if ( has_logs )
{
//Use the debug log to reconstruct the URL to send the crash report to
if(mDebugLog.has("CurrentSimHost"))
{
mCrashHost = "http://viewercrashreport";
fqdn = mDebugLog["CurrentSimHost"].asString();
boost::regex sim_re( "sim[[:digit:]]+.[[:alpha:]]+.lindenlab.com" );
boost::match_results<std::string::const_iterator> results;
if ( regex_match( fqdn, sim_re ) )
{
boost::regex regex_delimited("\\.[[:alpha:]]+\\.");
boost::match_flag_type flags = boost::match_default;
std::string::const_iterator start = fqdn.begin();
std::string::const_iterator end = fqdn.end();
boost::regex_search(start, end, results, regex_delimited, flags);
grid = std::string(results[0].first, results[0].second);
mCrashHost += grid;
mCrashHost += "lindenlab.com/cgi-bin/viewercrashreceiver.py";
}
else
{
mCrashHost = "";
}
// Use login servers as the alternate, since they are already load balanced and have a known name
mAltCrashHost = "https://login.agni.lindenlab.com:12043/crash/report";
}
}
//default to agni, per product
mAltCrashHost = "http://viewercrashreport.agni.lindenlab.com/cgi-bin/viewercrashreceiver.py";
mCrashInfo["DebugLog"] = mDebugLog;
mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log");
@ -389,15 +410,15 @@ bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout)
{
gBreak = false;
for(int i = 0; i < retries; ++i)
{
updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
while(!gBreak)
{
updateApplication(); // No new message, just pump the IO
}
while(!gBreak)
{
ms_sleep(250);
updateApplication(); // No new message, just pump the IO
}
if(gSent)
{
return gSent;
@ -408,12 +429,13 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
bool LLCrashLogger::sendCrashLog(std::string dump_dir)
{
gDirUtilp->setDumpDir( dump_dir );
std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLifeCrashReport");
std::string report_file = dump_path + ".log";
gatherFiles();
LLSD post_data;
@ -423,18 +445,24 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir)
std::ofstream out_file(report_file.c_str());
LLSDSerialize::toPrettyXML(post_data, out_file);
out_file.flush();
out_file.close();
bool sent = false;
//*TODO: Translate
if(mCrashHost != "")
{
{
std::string msg = "Using derived crash server... ";
msg = msg+mCrashHost.c_str();
updateApplication(msg.c_str());
sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), 3, 5);
}
if(!sent)
{
updateApplication("Using alternate (default) server...");
sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5);
}
@ -446,65 +474,22 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir)
bool LLCrashLogger::sendCrashLogs()
{
//pertinent code from below moved into a subroutine.
LLSD locks = mKeyMaster.getProcessList();
LLSD newlocks = LLSD::emptyArray();
LLSD opts = getOptionData(PRIORITY_COMMAND_LINE);
LLSD rec;
if ( opts.has("pid") && opts.has("dumpdir") && opts.has("procname") )
if ( opts.has("dumpdir") )
{
rec["pid"]=opts["pid"];
rec["dumpdir"]=opts["dumpdir"];
rec["procname"]=opts["procname"];
}
if (locks.isArray())
else
{
for (LLSD::array_iterator lock=locks.beginArray();
lock !=locks.endArray();
++lock)
{
if ( (*lock).has("pid") && (*lock).has("dumpdir") && (*lock).has("procname") )
{
if ( mKeyMaster.isProcessAlive( (*lock)["pid"].asInteger(), (*lock)["procname"].asString() ) )
{
newlocks.append(*lock);
}
else
{
//TODO: This is a hack but I didn't want to include boost in another file or retest everything related to lldir
if (LLCrashLock::fileExists((*lock)["dumpdir"].asString()))
{
//the viewer cleans up the log directory on clean shutdown
//but is ignorant of the locking table.
if (!sendCrashLog((*lock)["dumpdir"].asString()))
{
newlocks.append(*lock); //Failed to send log so don't delete it.
}
else
{
//mCrashInfo["DebugLog"].erase("MinidumpPath");
return false;
}
mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
}
}
}
}
else
{
LL_WARNS() << "Discarding corrupted entry from lock table." << LL_ENDL;
}
}
}
return sendCrashLog(rec["dumpdir"].asString());
if (rec)
{
newlocks.append(rec);
}
mKeyMaster.putProcessList(newlocks);
return true;
}
@ -540,25 +525,7 @@ bool LLCrashLogger::init()
// Set the log file to crashreport.log
LLError::logToFile(log_file); //NOTE: Until this line, LL_INFOS LL_WARNS, etc are blown to the ether.
// Handle locking
bool locked = mKeyMaster.requestMaster(); //Request master locking file. wait time is defaulted to 300S
while (!locked && mKeyMaster.isWaiting())
{
LL_INFOS("CRASHREPORT") << "Waiting for lock." << LL_ENDL;
#if LL_WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
locked = mKeyMaster.checkMaster();
}
if (!locked)
{
LL_WARNS("CRASHREPORT") << "Unable to get master lock. Another crash reporter may be hung." << LL_ENDL;
return false;
}
LL_INFOS() << "Crash reporter file rotation complete." << LL_ENDL;
mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
"Controls behavior when viewer crashes "

View File

@ -46,7 +46,7 @@ public:
LLCrashLogger();
virtual ~LLCrashLogger();
S32 loadCrashBehaviorSetting();
bool readDebugFromXML(LLSD& dest, const std::string& filename );
bool readFromXML(LLSD& dest, const std::string& filename );
void gatherFiles();
void mergeLogs( LLSD src_sd );

View File

@ -66,6 +66,7 @@ void LLCrashLoggerMac::gatherPlatformSpecificFiles()
bool LLCrashLoggerMac::mainLoop()
{
if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
{
gSendReport = true;
@ -82,6 +83,8 @@ bool LLCrashLoggerMac::mainLoop()
setUserText(gUserNotes);
sendCrashLogs();
}
LL_INFOS() << "Sending of logs complete" << LL_ENDL;
return true;
}

View File

@ -39,16 +39,17 @@ int main(int argc, char **argv)
LLSD options = LLApp::instance()->getOptionData(
LLApp::PRIORITY_COMMAND_LINE);
if (!(options.has("pid") && options.has("dumpdir")))
{
llwarns << "Insufficient parameters to crash report." << llendl;
}
if (! app.init())
{
LL_WARNS() << "Unable to initialize application." << LL_ENDL;
return 1;
}
if (!(options.has("pid") && options.has("dumpdir")))
{
LL_WARNS() << "Insufficient parameters to crash report." << llendl;
}
if (app.getCrashBehavior() != CRASH_BEHAVIOR_ALWAYS_SEND)
{
// return NSApplicationMain(argc, (const char **)argv);

View File

@ -82,10 +82,6 @@ static void exceptionTerminateHandler()
bool initViewer()
{
#if LL_SOLARIS && defined(__sparc)
asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
#endif
// Set the working dir to <bundle>/Contents/Resources
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
{
@ -296,6 +292,7 @@ void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)
std::string appname = gDirUtilp->getExecutableFilename();
std::string str[] = { "-pid", pid_str.str(), "-dumpdir", logdir, "-procname", appname.c_str() };
std::vector< std::string > args( str, str + ( sizeof ( str ) / sizeof ( std::string ) ) );
LL_WARNS() << "about to launch mac-crash-logger" << pid_str << " " << logdir << " " << appname << LL_ENDL;
launchApplication(&command_str, &args);
}