summaryrefslogtreecommitdiff
path: root/indra/llcrashlogger
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2016-04-20 11:52:00 -0400
committerOz Linden <oz@lindenlab.com>2016-04-20 11:52:00 -0400
commitecdb190d70a81294eebde7e53cf6a92139ba53d5 (patch)
tree6e7d97f6fdc682d1c89882884b03415e08fb3f2b /indra/llcrashlogger
parent85c9754a63cddca39b25d48504337d4e4c674a4f (diff)
MAINT-6322 fix merge error that prevented crash dumps from being located for upload (and add better logging)
Diffstat (limited to 'indra/llcrashlogger')
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp150
1 files changed, 121 insertions, 29 deletions
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 8e0a725954..4bfc2d40dd 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -162,6 +162,10 @@ bool LLCrashLogger::readFromXML(LLSD& dest, const std::string& filename )
log_file.close();
return true;
}
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "Failed to open " << db_file_name << LL_ENDL;
+ }
return false;
}
@@ -194,6 +198,11 @@ bool LLCrashLogger::readMinidump(std::string minidump_path)
mCrashInfo["Minidump"] = data;
}
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "failed to open minidump "<<minidump_path<<LL_ENDL;
+ }
+
return (length>0?true:false);
}
@@ -270,27 +279,36 @@ void LLCrashLogger::gatherFiles()
for(std::map<std::string, std::string>::iterator itr = mFileMap.begin(); itr != mFileMap.end(); ++itr)
{
- std::ifstream f((*itr).second.c_str());
- if(f.is_open())
+ std::string file = (*itr).second;
+ if (!file.empty())
{
- std::stringstream s;
- s << f.rdbuf();
-
- std::string crash_info = s.str();
- if(itr->first == "SecondLifeLog")
+ LL_DEBUGS("CRASHREPORT") << "trying to read " << itr->first << ": " << file << LL_ENDL;
+ std::ifstream f(file.c_str());
+ if(f.is_open())
{
- if(!mCrashInfo["DebugLog"].has("StartupState"))
+ std::stringstream s;
+ s << f.rdbuf();
+
+ std::string crash_info = s.str();
+ if(itr->first == "SecondLifeLog")
{
- mCrashInfo["DebugLog"]["StartupState"] = getStartupStateFromLog(crash_info);
+ if(!mCrashInfo["DebugLog"].has("StartupState"))
+ {
+ mCrashInfo["DebugLog"]["StartupState"] = getStartupStateFromLog(crash_info);
+ }
+ trimSLLog(crash_info);
}
- trimSLLog(crash_info);
- }
- mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info));
+ mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info));
+ }
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "Failed to open file " << file << LL_ENDL;
+ }
}
else
{
- LL_WARNS("CRASHREPORT") << "Can't find file " << (*itr).second << LL_ENDL;
+ LL_DEBUGS("CRASHREPORT") << "empty file in list for " << itr->first << LL_ENDL;
}
}
@@ -301,20 +319,21 @@ void LLCrashLogger::gatherFiles()
if (has_minidump)
{
minidump_path = mDebugLog["MinidumpPath"].asString();
- }
-
- if (has_minidump)
- {
has_minidump = readMinidump(minidump_path);
}
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "DebugLog does not have MinidumpPath" << LL_ENDL;
+ }
if (!has_minidump) //Viewer was probably so hosed it couldn't write remaining data. Try brute force.
{
- //Look for a filename at least 30 characters long in the dump dir which contains the characters MDMP as the first 4 characters in the file.
+ //Look for a filename at least 30 characters long in the dump dir which contains the characters MDMP as the first 4 characters in the file.
typedef std::vector<std::string> vec;
std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
+ LL_WARNS("CRASHREPORT") << "Searching for minidump in " << pathname << LL_ENDL;
vec file_vec = gDirUtilp->getFilesInDir(pathname);
- for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
+ for(vec::const_iterator iter=file_vec.begin(); !has_minidump && iter!=file_vec.end(); ++iter)
{
if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
{
@@ -330,15 +349,27 @@ void LLCrashLogger::gatherFiles()
minidump_path = *iter;
has_minidump = readMinidump(fullname);
mDebugLog["MinidumpPath"] = fullname;
- if (has_minidump)
- {
- break;
- }
+ }
+ else
+ {
+ LL_DEBUGS("CRASHREPORT") << "MDMP not found in " << fullname << LL_ENDL;
}
}
+ else
+ {
+ LL_DEBUGS("CRASHREPORT") << "failed to open " << fullname << LL_ENDL;
+ }
}
+ else
+ {
+ LL_DEBUGS("CRASHREPORT") << "Name does not match minidump name pattern " << *iter << LL_ENDL;
+ }
}
}
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "readMinidump returned no minidump" << LL_ENDL;
+ }
}
LLSD LLCrashLogger::constructPostData()
@@ -458,22 +489,63 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir)
bool LLCrashLogger::sendCrashLogs()
{
-
+ LLSD locks = mKeyMaster.getProcessList();
+ LLSD newlocks = LLSD::emptyArray();
+
LLSD opts = getOptionData(PRIORITY_COMMAND_LINE);
LLSD rec;
- if ( opts.has("dumpdir") )
+ if ( opts.has("pid") && opts.has("dumpdir") && opts.has("procname") )
{
rec["pid"]=opts["pid"];
rec["dumpdir"]=opts["dumpdir"];
rec["procname"]=opts["procname"];
}
- else
+
+ if (locks.isArray())
{
- return false;
- }
+ 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
+ {
+ mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_INFOS() << "Discarding corrupted entry from lock table." << LL_ENDL;
+ }
+ }
+ }
- return sendCrashLog(rec["dumpdir"].asString());
+ if (rec)
+ {
+ newlocks.append(rec);
+ }
+
+ mKeyMaster.putProcessList(newlocks);
+ return true;
}
void LLCrashLogger::updateApplication(const std::string& message)
@@ -510,6 +582,26 @@ bool LLCrashLogger::init()
LL_INFOS("CRASHREPORT") << "Crash reporter file rotation complete." << LL_ENDL;
+ // 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;
+ }
+
mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
"Controls behavior when viewer crashes "
"(0 = ask before sending crash report, "