diff options
author | Josh Bell <josh@lindenlab.com> | 2008-01-03 20:00:23 +0000 |
---|---|---|
committer | Josh Bell <josh@lindenlab.com> | 2008-01-03 20:00:23 +0000 |
commit | e1d40972220a6f90a2913b713e4daa665b188a56 (patch) | |
tree | 764d01011eb1801fa3603cea30380e4d71b5bc45 /indra/llcrashlogger/llcrashlogger.cpp | |
parent | b6e2a894f524b4dab1f3bb80572920fe926ed4c2 (diff) |
svn merge -r76651:76807 svn+ssh://svn.lindenlab.com/svn/linden/branches/Branch_1-18-6-Viewer --> release
Pick up fixes for:
* DEV-7598 VWR-3829: Cursor in Logon edit boxes difficult to see
* DEV-8125 Language names need to have a consistent format in preferences drop-down
* DEV-8099 SVC-1125: New Search: Beacons aren't shown when teleporting to regions with "Allow Direct Teleport" disabled
* DEV-8107 Crash when connecting to older sims in llviewerparcelmgr age verification code
* DEV-8130 Remove "Alternate Server" option from crash reporter since util.* no longer have public interfaces
* DEV-7372 VWR-3748: Builds fail on 1.18.6 RC if not using MOZLIB due to missing #if LL_LIBXUL_ENABLED in 3 places in indra/newview/llpanellogin.cpp
Plus corrected line endings for llcrashlogger.* (there's one actual change in those files, the rest is whitespace)
Diffstat (limited to 'indra/llcrashlogger/llcrashlogger.cpp')
-rwxr-xr-x | indra/llcrashlogger/llcrashlogger.cpp | 623 |
1 files changed, 314 insertions, 309 deletions
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index cec2b2e2e9..df446a7239 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -1,309 +1,314 @@ -/**
-* @file llcrashlogger.cpp
-* @brief Crash logger implementation
-*
-* $LicenseInfo:firstyear=2003&license=viewergpl$
-*
-* Copyright (c) 2003-2007, Linden Research, Inc.
-*
-* Second Life Viewer Source Code
-* The source code in this file ("Source Code") is provided by Linden Lab
-* to you under the terms of the GNU General Public License, version 2.0
-* ("GPL"), unless you have obtained a separate licensing agreement
-* ("Other License"), formally executed by you and Linden Lab. Terms of
-* the GPL can be found in doc/GPL-license.txt in this distribution, or
-* online at http://secondlife.com/developers/opensource/gplv2
-*
-* There are special exceptions to the terms and conditions of the GPL as
-* it is applied to this Source Code. View the full text of the exception
-* in the file doc/FLOSS-exception.txt in this software distribution, or
-* online at http://secondlife.com/developers/opensource/flossexception
-*
-* By copying, modifying or distributing this software, you acknowledge
-* that you have read and understood your obligations described above,
-* and agree to abide by those obligations.
-*
-* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-* COMPLETENESS OR PERFORMANCE.
-* $/LicenseInfo$
-*/
-#include <cstdio>
-#include <cstdlib>
-#include <sstream>
-#include <map>
-
-#include "llcrashlogger.h"
-#include "linden_common.h"
-#include "llstring.h"
-#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
-#include "llerror.h"
-#include "lltimer.h"
-#include "lldir.h"
-#include "llsdserialize.h"
-#include "lliopipe.h"
-#include "llpumpio.h"
-#include "llhttpclient.h"
-#include "llsdserialize.h"
-
-LLPumpIO* gServicePump;
-BOOL gBreak = false;
-BOOL gSent = false;
-
-class LLCrashLoggerResponder : public LLHTTPClient::Responder
-{
-public:
- LLCrashLoggerResponder()
- {
- }
-
- virtual void error(U32 status, const std::string& reason)
- {
- gBreak = true;
- }
-
- virtual void result(const LLSD& content)
- {
- gBreak = true;
- gSent = true;
- }
-};
-
-bool LLCrashLoggerText::mainLoop()
-{
- std::cout << "Entering main loop" << std::endl;
- sendCrashLogs();
- return true;
-}
-
-void LLCrashLoggerText::updateApplication(LLString message)
-{
- LLCrashLogger::updateApplication(message);
- std::cout << message << std::endl;
-}
-
-LLCrashLogger::LLCrashLogger() :
-mSentCrashLogs(false)
-{
-
-}
-
-LLCrashLogger::~LLCrashLogger()
-{
-
-}
-
-void LLCrashLogger::gatherFiles()
-{
-
- /*
- //TODO:This function needs to be reimplemented somewhere in here...
- if(!previous_crash && is_crash_log)
- {
- // Make sure the file isn't too old.
- double age = difftime(gLaunchTime, stat_data.st_mtimespec.tv_sec);
-
- // llinfos << "age is " << age << llendl;
-
- if(age > 60.0)
- {
- // The file was last modified more than 60 seconds before the crash reporter was launched. Assume it's stale.
- llwarns << "File " << mFilename << " is too old!" << llendl;
- return;
- }
- }
- */
-
- updateApplication("Gathering logs...");
-
- // Figure out the filename of the debug log
- LLString db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log").c_str();
- std::ifstream debug_log_file(db_file_name.c_str());
-
- // Look for it in the debug_info.log file
- if (debug_log_file.is_open())
- {
- LLSDSerialize::fromXML(mDebugLog, debug_log_file);
- mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString();
- mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString();
- LLHTTPClient::setCABundle(mDebugLog["CAFilename"].asString());
- llinfos << "Using log file from debug log " << mFileMap["SecondLifeLog"] << llendl;
- llinfos << "Using settings file from debug log " << mFileMap["SettingsXml"] << llendl;
- }
- else
- {
- // Figure out the filename of the second life log
- LLHTTPClient::setCABundle(gDirUtilp->getCAFile());
- mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
- mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
- }
-
- gatherPlatformSpecificFiles();
-
- //Use the debug log to reconstruct the URL to send the crash report to
- mCrashHost = "https://";
- mCrashHost += mDebugLog["CurrentSimHost"].asString();
- mCrashHost += ":12043/crash/report";
- mAltCrashHost = "https://";
- mAltCrashHost += mDebugLog["GridUtilHost"].asString();
- mAltCrashHost += ":12043/crash/report";
-
- mCrashInfo["DebugLog"] = mDebugLog;
- mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
- mFileMap["StackTrace"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
-
- updateApplication("Encoding files...");
-
- for(std::map<LLString, LLString>::iterator itr = mFileMap.begin(); itr != mFileMap.end(); ++itr)
- {
- std::ifstream f((*itr).second.c_str());
- if(!f.is_open())
- {
- std::cout << "Can't find file " << (*itr).second.c_str() << std::endl;
- continue;
- }
- std::stringstream s;
- s << f.rdbuf();
- mCrashInfo[(*itr).first] = s.str();
- }
-}
-
-LLSD LLCrashLogger::constructPostData()
-{
- LLSD ret;
-
- if(mCrashInPreviousExec)
- {
- mCrashInfo["CrashInPreviousExecution"] = "Y";
- }
-
- return mCrashInfo;
-}
-
-S32 LLCrashLogger::loadCrashBehaviorSetting()
-{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-
- mCrashSettings.loadFromFile(filename);
-
- S32 value = mCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
-
- if (value < CRASH_BEHAVIOR_ASK || CRASH_BEHAVIOR_NEVER_SEND < value) return CRASH_BEHAVIOR_ASK;
-
- return value;
-}
-
-bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
-{
- if (crash_behavior < CRASH_BEHAVIOR_ASK) return false;
- if (crash_behavior > CRASH_BEHAVIOR_NEVER_SEND) return false;
-
- mCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior);
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-
- mCrashSettings.saveToFile(filename, FALSE);
-
- return true;
-}
-
-bool LLCrashLogger::sendCrashLogs()
-{
- gatherFiles();
-
- LLSD post_data;
- post_data = constructPostData();
-
- updateApplication("Sending reports...");
-
- std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLifeCrashReport");
- std::string report_file = dump_path + ".log";
-
- std::ofstream out_file(report_file.c_str());
- LLSDSerialize::toPrettyXML(post_data, out_file);
- out_file.close();
- LLHTTPClient::post(mCrashHost, post_data, new LLCrashLoggerResponder(), 5);
-
- gBreak = false;
- while(!gBreak)
- {
- updateApplication("Sending logs...");
- }
-
- if(!gSent)
- {
- gBreak = false;
- LLHTTPClient::post(mAltCrashHost, post_data, new LLCrashLoggerResponder(), 5);
-
- while(!gBreak)
- {
- updateApplication("Sending logs to Alternate Server...");
- }
- }
- mSentCrashLogs = gSent;
-
- return true;
-}
-
-void LLCrashLogger::updateApplication(LLString message)
-{
- gServicePump->pump();
- gServicePump->callback();
-}
-
-bool LLCrashLogger::init()
-{
- // We assume that all the logs we're looking for reside on the current drive
- gDirUtilp->initAppDirs("SecondLife");
-
- // Default to the product name "Second Life" (this is overridden by the -name argument)
- mProductName = "Second Life";
-
- mCrashSettings.declareS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ASK, "Controls behavior when viewer crashes "
- "(0 = ask before sending crash report, 1 = always send crash report, 2 = never send crash report)");
-
- llinfos << "Loading crash behavior setting" << llendl;
- mCrashBehavior = loadCrashBehaviorSetting();
-
- //Run through command line options
- if(getOption("previous").isDefined())
- {
- llinfos << "Previous execution did not remove SecondLife.exec_marker" << llendl;
- mCrashInPreviousExec = TRUE;
- }
-
- if(getOption("dialog").isDefined())
- {
- llinfos << "Show the user dialog" << llendl;
- mCrashBehavior = CRASH_BEHAVIOR_ASK;
- }
-
- LLSD server = getOption("user");
- if(server.isDefined())
- {
- mGridName = server.asString();
- llinfos << "Got userserver " << mGridName << llendl;
- }
- else
- {
- mGridName = "agni";
- }
-
- LLSD name = getOption("name");
- if(name.isDefined())
- {
- mProductName = name.asString();
- }
-
- // If user doesn't want to send, bail out
- if (mCrashBehavior == CRASH_BEHAVIOR_NEVER_SEND)
- {
- llinfos << "Crash behavior is never_send, quitting" << llendl;
- return false;
- }
-
- gServicePump = new LLPumpIO(gAPRPoolp);
- gServicePump->prime(gAPRPoolp);
- LLHTTPClient::setPump(*gServicePump);
- return true;
-}
+/** +* @file llcrashlogger.cpp +* @brief Crash logger implementation +* +* $LicenseInfo:firstyear=2003&license=viewergpl$ +* +* Copyright (c) 2003-2007, Linden Research, Inc. +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlife.com/developers/opensource/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlife.com/developers/opensource/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ +#include <cstdio> +#include <cstdlib> +#include <sstream> +#include <map> + +#include "llcrashlogger.h" +#include "linden_common.h" +#include "llstring.h" +#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME +#include "llerror.h" +#include "lltimer.h" +#include "lldir.h" +#include "llsdserialize.h" +#include "lliopipe.h" +#include "llpumpio.h" +#include "llhttpclient.h" +#include "llsdserialize.h" + +LLPumpIO* gServicePump; +BOOL gBreak = false; +BOOL gSent = false; + +class LLCrashLoggerResponder : public LLHTTPClient::Responder +{ +public: + LLCrashLoggerResponder() + { + } + + virtual void error(U32 status, const std::string& reason) + { + gBreak = true; + } + + virtual void result(const LLSD& content) + { + gBreak = true; + gSent = true; + } +}; + +bool LLCrashLoggerText::mainLoop() +{ + std::cout << "Entering main loop" << std::endl; + sendCrashLogs(); + return true; +} + +void LLCrashLoggerText::updateApplication(LLString message) +{ + LLCrashLogger::updateApplication(message); + std::cout << message << std::endl; +} + +LLCrashLogger::LLCrashLogger() : +mSentCrashLogs(false) +{ + +} + +LLCrashLogger::~LLCrashLogger() +{ + +} + +void LLCrashLogger::gatherFiles() +{ + + /* + //TODO:This function needs to be reimplemented somewhere in here... + if(!previous_crash && is_crash_log) + { + // Make sure the file isn't too old. + double age = difftime(gLaunchTime, stat_data.st_mtimespec.tv_sec); + + // llinfos << "age is " << age << llendl; + + if(age > 60.0) + { + // The file was last modified more than 60 seconds before the crash reporter was launched. Assume it's stale. + llwarns << "File " << mFilename << " is too old!" << llendl; + return; + } + } + */ + + updateApplication("Gathering logs..."); + + // Figure out the filename of the debug log + LLString db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log").c_str(); + std::ifstream debug_log_file(db_file_name.c_str()); + + // Look for it in the debug_info.log file + if (debug_log_file.is_open()) + { + LLSDSerialize::fromXML(mDebugLog, debug_log_file); + mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString(); + mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString(); + LLHTTPClient::setCABundle(mDebugLog["CAFilename"].asString()); + llinfos << "Using log file from debug log " << mFileMap["SecondLifeLog"] << llendl; + llinfos << "Using settings file from debug log " << mFileMap["SettingsXml"] << llendl; + } + else + { + // Figure out the filename of the second life log + LLHTTPClient::setCABundle(gDirUtilp->getCAFile()); + mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); + mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml"); + } + + gatherPlatformSpecificFiles(); + + //Use the debug log to reconstruct the URL to send the crash report to + mCrashHost = "https://"; + mCrashHost += mDebugLog["CurrentSimHost"].asString(); + mCrashHost += ":12043/crash/report"; + mAltCrashHost = "https://"; + mAltCrashHost += mDebugLog["GridUtilHost"].asString(); + mAltCrashHost += ":12043/crash/report"; + + mCrashInfo["DebugLog"] = mDebugLog; + mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log"); + mFileMap["StackTrace"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); + + updateApplication("Encoding files..."); + + for(std::map<LLString, LLString>::iterator itr = mFileMap.begin(); itr != mFileMap.end(); ++itr) + { + std::ifstream f((*itr).second.c_str()); + if(!f.is_open()) + { + std::cout << "Can't find file " << (*itr).second.c_str() << std::endl; + continue; + } + std::stringstream s; + s << f.rdbuf(); + mCrashInfo[(*itr).first] = s.str(); + } +} + +LLSD LLCrashLogger::constructPostData() +{ + LLSD ret; + + if(mCrashInPreviousExec) + { + mCrashInfo["CrashInPreviousExecution"] = "Y"; + } + + return mCrashInfo; +} + +S32 LLCrashLogger::loadCrashBehaviorSetting() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); + + mCrashSettings.loadFromFile(filename); + + S32 value = mCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); + + if (value < CRASH_BEHAVIOR_ASK || CRASH_BEHAVIOR_NEVER_SEND < value) return CRASH_BEHAVIOR_ASK; + + return value; +} + +bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior) +{ + if (crash_behavior < CRASH_BEHAVIOR_ASK) return false; + if (crash_behavior > CRASH_BEHAVIOR_NEVER_SEND) return false; + + mCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior); + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); + + mCrashSettings.saveToFile(filename, FALSE); + + return true; +} + +bool LLCrashLogger::sendCrashLogs() +{ + gatherFiles(); + + LLSD post_data; + post_data = constructPostData(); + + updateApplication("Sending reports..."); + + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + "SecondLifeCrashReport"); + std::string report_file = dump_path + ".log"; + + std::ofstream out_file(report_file.c_str()); + LLSDSerialize::toPrettyXML(post_data, out_file); + out_file.close(); + LLHTTPClient::post(mCrashHost, post_data, new LLCrashLoggerResponder(), 5); + + gBreak = false; + while(!gBreak) + { + updateApplication("Sending logs..."); + } + + //util.* servers no longer have a public interface, so there's no alternate server anymore. + //leaving this in if we decide we need another alternate server for crash report receiving. + /* + if(!gSent) + { + gBreak = false; + LLHTTPClient::post(mAltCrashHost, post_data, new LLCrashLoggerResponder(), 5); + + while(!gBreak) + { + updateApplication("Sending logs to Alternate Server..."); + } + } + */ + + mSentCrashLogs = gSent; + + return true; +} + +void LLCrashLogger::updateApplication(LLString message) +{ + gServicePump->pump(); + gServicePump->callback(); +} + +bool LLCrashLogger::init() +{ + // We assume that all the logs we're looking for reside on the current drive + gDirUtilp->initAppDirs("SecondLife"); + + // Default to the product name "Second Life" (this is overridden by the -name argument) + mProductName = "Second Life"; + + mCrashSettings.declareS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ASK, "Controls behavior when viewer crashes " + "(0 = ask before sending crash report, 1 = always send crash report, 2 = never send crash report)"); + + llinfos << "Loading crash behavior setting" << llendl; + mCrashBehavior = loadCrashBehaviorSetting(); + + //Run through command line options + if(getOption("previous").isDefined()) + { + llinfos << "Previous execution did not remove SecondLife.exec_marker" << llendl; + mCrashInPreviousExec = TRUE; + } + + if(getOption("dialog").isDefined()) + { + llinfos << "Show the user dialog" << llendl; + mCrashBehavior = CRASH_BEHAVIOR_ASK; + } + + LLSD server = getOption("user"); + if(server.isDefined()) + { + mGridName = server.asString(); + llinfos << "Got userserver " << mGridName << llendl; + } + else + { + mGridName = "agni"; + } + + LLSD name = getOption("name"); + if(name.isDefined()) + { + mProductName = name.asString(); + } + + // If user doesn't want to send, bail out + if (mCrashBehavior == CRASH_BEHAVIOR_NEVER_SEND) + { + llinfos << "Crash behavior is never_send, quitting" << llendl; + return false; + } + + gServicePump = new LLPumpIO(gAPRPoolp); + gServicePump->prime(gAPRPoolp); + LLHTTPClient::setPump(*gServicePump); + return true; +} |