diff options
author | Oz Linden <oz@lindenlab.com> | 2016-04-20 11:52:00 -0400 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2016-04-20 11:52:00 -0400 |
commit | ddd476c90c99c75a4add6c00243a90e84e025402 (patch) | |
tree | 5ec50ad42336e167305c4d4146eef4b1e14d5aac /indra | |
parent | a6bc849992ea120e6d05ac4b6ddf61c9ee807588 (diff) |
MAINT-6322 fix merge error that prevented crash dumps from being located for upload (and add better logging)
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/llcommon/llapp.cpp | 6 | ||||
-rwxr-xr-x | indra/llcrashlogger/llcrashlogger.cpp | 150 | ||||
-rwxr-xr-x | indra/newview/llappviewer.cpp | 18 |
3 files changed, 136 insertions, 38 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 5a40845e7d..eb0699ad41 100755 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -929,7 +929,7 @@ bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_ strncpy(path, minidump_desc.path(), remaining); - LL_INFOS() << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; + LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; LLApp::runErrorHandler(); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -975,7 +975,7 @@ bool unix_post_minidump_callback(const char *dump_dir, strncpy(path, ".dmp", remaining); } - LL_INFOS() << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; + LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; LLApp::runErrorHandler(); #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -1019,7 +1019,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, strncpy(path, ".dmp", remaining); } - LL_INFOS() << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; + LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. //OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); // *TODO: Translate the signals/exceptions into cross-platform stuff diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 9fd6b66513..7e52eb231a 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -161,6 +161,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; } @@ -193,6 +197,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); } @@ -269,27 +278,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; } } @@ -300,20 +318,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) ) ) { @@ -329,15 +348,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() @@ -457,22 +488,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) @@ -509,6 +581,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, " diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 212627c0f7..45306dcff4 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3615,9 +3615,9 @@ void getFileList() void LLAppViewer::handleViewerCrash() { - LL_INFOS() << "Handle viewer crash entry." << LL_ENDL; + LL_INFOS("CRASHREPORT") << "Handle viewer crash entry." << LL_ENDL; - LL_INFOS() << "Last render pool type: " << LLPipeline::sCurRenderPoolType << LL_ENDL ; + LL_INFOS("CRASHREPORT") << "Last render pool type: " << LLPipeline::sCurRenderPoolType << LL_ENDL ; LLMemory::logMemoryInfo(true) ; @@ -3725,30 +3725,36 @@ void LLAppViewer::handleViewerCrash() #endif char *minidump_file = pApp->getMiniDumpFilename(); - + LL_DEBUGS("CRASHREPORT") << "minidump file name " << minidump_file << LL_ENDL; if(minidump_file && minidump_file[0] != 0) { gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file; } -#ifdef LL_WINDOWS else { +#ifdef LL_WINDOWS getFileList(); +#else + LL_WARNS("CRASHREPORT") << "no minidump file?" << LL_ENDL; +#endif } -#endif gDebugInfo["Dynamic"]["CrashType"]="crash"; if (gMessageSystem && gDirUtilp) { std::string filename; filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log"); + LL_DEBUGS("CRASHREPORT") << "recording stats " << filename << LL_ENDL; llofstream file(filename.c_str(), std::ios_base::binary); if(file.good()) { - LL_INFOS() << "Handle viewer crash generating stats log." << LL_ENDL; gMessageSystem->summarizeLogs(file); file.close(); } + else + { + LL_WARNS("CRASHREPORT") << "problem recording stats" << LL_ENDL; + } } if (gMessageSystem) |