Imported Viewer-CrashReporting patch (based on changeset 1f48d184812d)

master
Kitty Barnett 2011-05-08 14:41:26 +02:00
parent de6b199ee1
commit 2bf2874f3f
21 changed files with 873 additions and 65 deletions

View File

@ -282,7 +282,10 @@ void LLApp::stepFrame()
}
void LLApp::setupErrorHandling()
//void LLApp::setupErrorHandling()
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-12 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
void LLApp::setupErrorHandling(EMiniDumpType minidump_type)
// [/SL:KB]
{
// Error handling is done by starting up an error handling thread, which just sleeps and
// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
@ -296,8 +299,27 @@ void LLApp::setupErrorHandling()
if(mExceptionHandler == 0)
{
llwarns << "adding breakpad exception handler" << llendl;
// mExceptionHandler = new google_breakpad::ExceptionHandler(
// L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-12 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
U32 maskMiniDumpType = MiniDumpNormal | MiniDumpFilterModulePaths;
switch (minidump_type)
{
case MINIDUMP_MINIMAL:
maskMiniDumpType |= MiniDumpFilterMemory;
break;
case MINIDUMP_EXTENDED:
maskMiniDumpType |= MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory;
break;
case MINIDUMP_NORMAL:
default:
break;
}
mExceptionHandler = new google_breakpad::ExceptionHandler(
L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);
L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL,
(MINIDUMP_TYPE)maskMiniDumpType, NULL, NULL);
// [/SL:KB]
}
#else

View File

@ -227,7 +227,15 @@ public:
* DO NOT call this method if your application has specialized
* error handling code.
*/
void setupErrorHandling();
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-12 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
typedef enum minidump_type_t {
MINIDUMP_MINIMAL = 0,
MINIDUMP_NORMAL = 1,
MINIDUMP_EXTENDED = 2
} EMiniDumpType;
void setupErrorHandling(EMiniDumpType minidump_type = MINIDUMP_NORMAL);
// [/SL:KB]
void setErrorHandler(LLAppErrorHandler handler);
static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.

View File

@ -19,12 +19,14 @@ include_directories(
set(llcrashlogger_SOURCE_FILES
llcrashlogger.cpp
llcrashlookup.cpp
)
set(llcrashlogger_HEADER_FILES
CMakeLists.txt
llcrashlogger.h
llcrashlookup.h
)
set_source_files_properties(${llcrashlogger_HEADER_FILES}

View File

@ -41,6 +41,10 @@
#include "llhttpclient.h"
#include "llsdserialize.h"
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
#include <shellapi.h>
// [/SL:KB]
LLPumpIO* gServicePump;
BOOL gBreak = false;
BOOL gSent = false;
@ -58,7 +62,14 @@ public:
}
virtual void result(const LLSD& content)
{
{
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
if ( (content.has("crash_link")) && (!content["crash_link"].asString().empty()) )
{
((LLCrashLogger*)LLCrashLogger::instance())->setCrashInformationLink(content["crash_link"].asString());
}
// [/SL:KB]
gBreak = true;
gSent = true;
}
@ -78,6 +89,9 @@ void LLCrashLoggerText::updateApplication(const std::string& message)
}
LLCrashLogger::LLCrashLogger() :
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
mCrashLookup(NULL),
// [/SL:KB]
mCrashBehavior(CRASH_BEHAVIOR_ASK),
mCrashInPreviousExec(false),
mCrashSettings("CrashSettings"),
@ -176,6 +190,7 @@ void LLCrashLogger::gatherFiles()
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
@ -183,6 +198,7 @@ void LLCrashLogger::gatherFiles()
mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
}
*/
if(mCrashInPreviousExec)
{
@ -203,6 +219,13 @@ void LLCrashLogger::gatherFiles()
// Crash log receiver has been manually configured.
mCrashHost = mDebugLog["CrashHostUrl"].asString();
}
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2011-03-24 (Catznip-2.6.0a) | Modified: Catznip-2.6.0a
else
{
mCrashHost = "http://catznip.com/viewer/crash/report/2.6/";
}
// [/SL:KB]
/*
else if(mDebugLog.has("CurrentSimHost"))
{
mCrashHost = "https://";
@ -219,15 +242,20 @@ void LLCrashLogger::gatherFiles()
mCrashHost += grid_host;
mCrashHost += ".lindenlab.com:12043/crash/report";
}
*/
// 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";
// mAltCrashHost = "https://login.agni.lindenlab.com:12043/crash/report";
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
mAltCrashHost = "";
// [/SL:KB]
mCrashInfo["DebugLog"] = mDebugLog;
// mCrashInfo["DebugLog"] = mDebugLog;
mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
updateApplication("Encoding files...");
/*
for(std::map<std::string, std::string>::iterator itr = mFileMap.begin(); itr != mFileMap.end(); ++itr)
{
std::ifstream f((*itr).second.c_str());
@ -251,9 +279,23 @@ void LLCrashLogger::gatherFiles()
mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info));
}
*/
// Add minidump as binary.
std::string minidump_path = mDebugLog["MinidumpPath"];
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2011-03-24 (Catznip-2.6.0a) | Modified: Catznip-2.6.0a
if (gDirUtilp->fileExists(minidump_path))
{
mFileMap["Minidump"] = minidump_path;
mCrashLookup->initFromDump(minidump_path);
// Remove the minidump path after we've retrieved it since it could contain the OS user name
mDebugLog.erase("MinidumpPath");
}
// Include debug_info.log as part of CrashReport.log
mCrashInfo["DebugLog"] = mDebugLog;
// [/SL:KB]
/*
if(minidump_path != "")
{
std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary);
@ -273,6 +315,7 @@ void LLCrashLogger::gatherFiles()
}
}
mCrashInfo["DebugLog"].erase("MinidumpPath");
*/
}
LLSD LLCrashLogger::constructPostData()
@ -306,6 +349,19 @@ bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
return true;
}
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
std::string getFormDataField(const std::string& strFieldName, const std::string& strFieldValue, const std::string& strBoundary)
{
std::ostringstream streamFormPart;
streamFormPart << "--" << strBoundary << "\r\n"
<< "Content-Disposition: form-data; name=\"" << strFieldName << "\"\r\n\r\n"
<< strFieldValue << "\r\n";
return streamFormPart.str();
}
// [/SL:KB]
bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout)
{
gBreak = false;
@ -313,7 +369,72 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
for(int i = 0; i < retries; ++i)
{
status_message = llformat("%s, try %d...", msg.c_str(), i+1);
LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
// LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2011-03-24 (Catznip-2.6.0a) | Modified: Catznip-2.6.0a
static const std::string BOUNDARY("------------abcdef012345xyZ");
LLSD headers = LLSD::emptyMap();
headers["Accept"] = "*/*";
headers["Content-Type"] = "multipart/form-data; boundary=" + BOUNDARY;
std::ostringstream body;
/*
* Include crash analysis pony
*/
body << getFormDataField("crash_module_name", mCrashLookup->getModuleName(), BOUNDARY);
body << getFormDataField("crash_module_version", llformat("%I64d", mCrashLookup->getModuleVersion()), BOUNDARY);
body << getFormDataField("crash_module_versionstring", mCrashLookup->getModuleVersionString(), BOUNDARY);
body << getFormDataField("crash_module_displacement", llformat("%I64d", mCrashLookup->getModuleDisplacement()), BOUNDARY);
/*
* Add the actual crash logs
*/
for (std::map<std::string, std::string>::const_iterator itFile = mFileMap.begin(), endFile = mFileMap.end();
itFile != endFile; ++itFile)
{
if (itFile->second.empty())
continue;
body << "--" << BOUNDARY << "\r\n"
<< "Content-Disposition: form-data; name=\"crash_report[]\"; "
<< "filename=\"" << gDirUtilp->getBaseFileName(itFile->second) << "\"\r\n"
<< "Content-Type: application/octet-stream"
<< "\r\n\r\n";
llifstream fstream(itFile->second, std::iostream::binary | std::iostream::out);
if (fstream.is_open())
{
fstream.seekg(0, std::ios::end);
U32 fileSize = fstream.tellg();
fstream.seekg(0, std::ios::beg);
std::vector<char> fileBuffer(fileSize);
fstream.read(&fileBuffer[0], fileSize);
body.write(&fileBuffer[0], fileSize);
fstream.close();
}
body << "\r\n";
}
/*
* Close the post
*/
body << "--" << BOUNDARY << "--\r\n";
// postRaw() takes ownership of the buffer and releases it later.
size_t size = body.str().size();
U8 *data = new U8[size];
memcpy(data, body.str().data(), size);
// Send request
LLHTTPClient::postRaw(host, data, size, new LLCrashLoggerResponder(), headers);
// [/SL:KB]
while(!gBreak)
{
updateApplication(status_message);
@ -335,14 +456,22 @@ bool LLCrashLogger::sendCrashLogs()
updateApplication("Sending reports...");
// std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
// "SecondLifeCrashReport");
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLifeCrashReport");
"CatznipCrashReport");
// [/SL:KB]
std::string report_file = dump_path + ".log";
std::ofstream out_file(report_file.c_str());
LLSDSerialize::toPrettyXML(post_data, out_file);
out_file.close();
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
mFileMap["CrashReportLog"] = report_file;
// [/SL:KB]
bool sent = false;
//*TODO: Translate
@ -351,13 +480,36 @@ bool LLCrashLogger::sendCrashLogs()
sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), 3, 5);
}
if(!sent)
// if(!sent)
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
if ( (!sent) && (!mAltCrashHost.empty()) )
// [/SL:KB]
{
sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5);
}
mSentCrashLogs = sent;
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
if (!mCrashLink.empty())
{
#ifdef LL_WINDOWS
if (IDYES == MessageBox(NULL, L"Additional information is available about this crash. Display?", L"Crash Information", MB_YESNO))
{
wchar_t wstrCrashLink[512];
mbstowcs_s(NULL, wstrCrashLink, 512, mCrashLink.c_str(), _TRUNCATE);
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOASYNC;
sei.lpVerb = L"open";
sei.lpFile = wstrCrashLink;
ShellExecuteEx(&sei);
}
#endif // LL_WINDOWS
}
// [/SL:KB]
return true;
}

View File

@ -33,6 +33,9 @@
#include "llapp.h"
#include "llsd.h"
#include "llcontrol.h"
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
#include "llcrashlookup.h"
// [/SL:KB]
class LLCrashLogger : public LLApp
{
@ -52,6 +55,10 @@ public:
void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }
S32 getCrashBehavior() { return mCrashBehavior; }
bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout);
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
std::string getCrashInformationLink() { return mCrashLink; }
void setCrashInformationLink(const std::string& strCrashLink) { mCrashLink = strCrashLink; }
// [/SL:KB]
protected:
S32 mCrashBehavior;
BOOL mCrashInPreviousExec;
@ -60,6 +67,10 @@ protected:
LLControlGroup mCrashSettings;
std::string mProductName;
LLSD mCrashInfo;
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
LLCrashLookup* mCrashLookup;
std::string mCrashLink;
// [/SL:KB]
std::string mCrashHost;
std::string mAltCrashHost;
LLSD mDebugLog;

View File

@ -0,0 +1,32 @@
/**
* @file llcrashlookup.cpp
* @brief Base crash analysis class
*
* Copyright (C) 2011, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "linden_common.h"
#include "llcrashlookup.h"
std::string LLCrashLookup::getModuleVersionString() const
{
std::string strVersion = llformat("%d.%d.%d.%d",
m_nModuleVersion >> 48, (m_nModuleVersion >> 32) & 0xFFFF, (m_nModuleVersion >> 16) & 0xFFFF, m_nModuleVersion & 0xFFFF);
return strVersion;
}

View File

@ -0,0 +1,56 @@
/**
* @file llcrashlookup.h
* @brief Base crash analysis class
*
* Copyright (C) 2011, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef LLCRASHLOOKUP_H
#define LLCRASHLOOKUP_H
#include <string>
class LLCrashLookup
{
public:
LLCrashLookup() {}
virtual ~LLCrashLookup() {}
public:
virtual bool initFromDump(const std::string& strDumpPath) = 0;
public:
U64 getInstructionAddress() const { return m_nInstructionAddr; }
const std::string& getModuleName() const { return m_strModule; }
U64 getModuleBaseAdress() const { return m_nModuleBaseAddr; }
U64 getModuleDisplacement() const { return m_nInstructionAddr - m_nModuleBaseAddr; }
U32 getModuleTimeStamp() const { return m_nModuleTimeStamp; }
U32 getModuleChecksum() const { return m_nModuleChecksum; }
U64 getModuleVersion() const { return m_nModuleVersion; }
std::string getModuleVersionString() const;
protected:
U64 m_nInstructionAddr; // Memory pony where the crash occurred
std::string m_strModule; // Name of the module in which the crash occurred
U64 m_nModuleBaseAddr; // Base memory address of the module
U32 m_nModuleTimeStamp; // The date and time stamp of the module
U32 m_nModuleChecksum; // The 32-bit checksum of the module image
U64 m_nModuleVersion; // The version of the module, packed into 64-bits
};
#endif // LLCRASHLOOKUP_H

View File

@ -9263,6 +9263,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>SaveMinidumpType</key>
<map>
<key>Comment</key>
<string>Type of minidump that is created (0 - minimal, 1 - normal [default], 2 - extended)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>ScaleShowAxes</key>
<map>
<key>Comment</key>

View File

@ -9,7 +9,29 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>2</integer>
<integer>0</integer>
</map>
<key>CrashSubmitName</key>
<map>
<key>Comment</key>
<string>Second Life name will be included with the crash report</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>CrashSubmitSettings</key>
<map>
<key>Comment</key>
<string>Per-user settings override will be sent along with the crash report</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -622,7 +622,14 @@ LLAppViewer::LLAppViewer() :
llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl;
}
setupErrorHandling();
// setupErrorHandling();
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-12 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
EMiniDumpType minidump_type = MINIDUMP_NORMAL;
if (gSavedSettings.controlExists("SaveMiniDumpType"))
minidump_type = (LLApp::EMiniDumpType)gSavedSettings.getU32("SaveMiniDumpType");
setupErrorHandling(minidump_type);
// [/SL:KB]
sInstance = this;
gLoggedInTime.stop();
@ -741,11 +748,11 @@ bool LLAppViewer::init()
// Get the single value from the crash settings file, if it exists
std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
gCrashSettings.loadFromFile(crash_settings_filename);
if(gSavedSettings.getBOOL("IgnoreAllNotifications"))
{
gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND);
gCrashSettings.saveToFile(crash_settings_filename, FALSE);
}
// if(gSavedSettings.getBOOL("IgnoreAllNotifications"))
// {
// gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND);
// gCrashSettings.saveToFile(crash_settings_filename, FALSE);
// }
/////////////////////////////////////////////////
// OS-specific login dialogs
@ -2849,7 +2856,7 @@ void LLAppViewer::removeCacheFiles(const std::string& file_mask)
void LLAppViewer::writeSystemInfo()
{
gDebugInfo["SLLog"] = LLError::logFileName();
// gDebugInfo["SLLog"] = LLError::logFileName();
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
@ -2857,7 +2864,7 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
// gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
gDebugInfo["CPUInfo"]["CPUFamily"] = gSysCPU.getFamily();
@ -2961,6 +2968,7 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
/*
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
{
@ -2970,12 +2978,20 @@ void LLAppViewer::handleViewerCrash()
{
gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
}
*/
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
// gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
if (gCrashSettings.getBOOL("CrashSubmitSettings"))
{
// Only include settings.xml if the user consented
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
}
// [/SL:KB]
// gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
// gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
// gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
@ -2997,6 +3013,11 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
}
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
// Current host and region would expose too much information, but do track the last server version
gDebugInfo["LastVersionChannel"] = gLastVersionChannel;
// [/SL:KB]
/*
if(gAgent.getRegion())
{
gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
@ -3007,6 +3028,7 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["CurrentLocationY"] = loc.mV[1];
gDebugInfo["CurrentLocationZ"] = loc.mV[2];
}
*/
if(LLAppViewer::instance()->mMainloopTimeout)
{
@ -3058,7 +3080,7 @@ void LLAppViewer::handleViewerCrash()
gMessageSystem->stopLogging();
}
if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
// if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
// Close the debug file
pApp->writeDebugInfo();
@ -4768,6 +4790,7 @@ void LLAppViewer::handleLoginComplete()
gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
/*
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
{
@ -4777,17 +4800,31 @@ void LLAppViewer::handleLoginComplete()
{
gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
}
*/
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
// gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
if (gCrashSettings.getBOOL("CrashSubmitSettings"))
{
// Only include settings.xml if the user consented
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
}
// [/SL:KB]
// gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
// gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
// gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
// Current host and region would expose too much information, but do track the last server version
gDebugInfo["LastVersionChannel"] = gLastVersionChannel;
// [/SL:KB]
/*
if(gAgent.getRegion())
{
gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
}
*/
if(LLAppViewer::instance()->mMainloopTimeout)
{

View File

@ -1915,6 +1915,73 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()
LLPanelPreference::setHardwareDefaults();
}
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
static LLRegisterPanelClassWrapper<LLPanelPreferenceCrashReports> t_pref_crashreports("panel_preference_crashreports");
LLPanelPreferenceCrashReports::LLPanelPreferenceCrashReports()
: LLPanelPreference()
{
}
BOOL LLPanelPreferenceCrashReports::postBuild()
{
S32 nCrashSubmitBehavior = gCrashSettings.getS32("CrashSubmitBehavior");
LLCheckBoxCtrl* pSendCrashReports = getChild<LLCheckBoxCtrl>("checkSendCrashReports");
pSendCrashReports->set(CRASH_BEHAVIOR_NEVER_SEND != nCrashSubmitBehavior);
pSendCrashReports->setCommitCallback(boost::bind(&LLPanelPreferenceCrashReports::refresh, this));
LLCheckBoxCtrl* pSendAlwaysAsk = getChild<LLCheckBoxCtrl>("checkSendCrashReportsAlwaysAsk");
pSendAlwaysAsk->set(CRASH_BEHAVIOR_ASK == nCrashSubmitBehavior);
LLCheckBoxCtrl* pSendSettings = getChild<LLCheckBoxCtrl>("checkSendSettings");
pSendSettings->set(gCrashSettings.getBOOL("CrashSubmitSettings"));
LLCheckBoxCtrl* pSendName = getChild<LLCheckBoxCtrl>("checkSendName");
pSendName->set(gCrashSettings.getBOOL("CrashSubmitName"));
refresh();
return LLPanelPreference::postBuild();
}
void LLPanelPreferenceCrashReports::refresh()
{
#if LL_WINDOWS
LLCheckBoxCtrl* pSendCrashReports = getChild<LLCheckBoxCtrl>("checkSendCrashReports");
pSendCrashReports->setEnabled(TRUE);
bool fEnable = pSendCrashReports->get();
getChild<LLUICtrl>("comboSaveMiniDumpType")->setEnabled(fEnable);
getChild<LLUICtrl>("checkSendCrashReportsAlwaysAsk")->setEnabled(fEnable);
getChild<LLUICtrl>("checkSendSettings")->setEnabled(fEnable);
getChild<LLUICtrl>("checkSendName")->setEnabled(fEnable);
#endif // LL_WINDOWS
}
void LLPanelPreferenceCrashReports::apply()
{
#if LL_WINDOWS
LLCheckBoxCtrl* pSendCrashReports = getChild<LLCheckBoxCtrl>("checkSendCrashReports");
LLCheckBoxCtrl* pSendAlwaysAsk = getChild<LLCheckBoxCtrl>("checkSendCrashReportsAlwaysAsk");
if (pSendCrashReports->get())
gCrashSettings.setS32("CrashSubmitBehavior", (pSendAlwaysAsk->get()) ? CRASH_BEHAVIOR_ASK : CRASH_BEHAVIOR_ALWAYS_SEND);
else
gCrashSettings.setS32("CrashSubmitBehavior", CRASH_BEHAVIOR_NEVER_SEND);
LLCheckBoxCtrl* pSendSettings = getChild<LLCheckBoxCtrl>("checkSendSettings");
gCrashSettings.setBOOL("CrashSubmitSettings", pSendSettings->get());
LLCheckBoxCtrl* pSendName = getChild<LLCheckBoxCtrl>("checkSendName");
gCrashSettings.setBOOL("CrashSubmitName", pSendName->get());
#endif // LL_WINDOWS
}
void LLPanelPreferenceCrashReports::cancel()
{
}
// [/SL:KB]
// <KB> - Catznip Viewer-Skins
static LLRegisterPanelClassWrapper<LLPanelPreferenceSkins> t_pref_skins("panel_preference_skins");

View File

@ -256,6 +256,20 @@ protected:
LLComboBox* m_pSkinThemeCombo;
LLSD m_SkinsInfo;
};
// [/SL:KB]
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-10-21 (Catznip-2.6.0a) | Added: Catznip-2.2.0c
class LLPanelPreferenceCrashReports : public LLPanelPreference
{
public:
LLPanelPreferenceCrashReports();
/*virtual*/ BOOL postBuild();
/*virtual*/ void apply();
/*virtual*/ void cancel();
void refresh();
};
// [/SL:KB]
#endif // LL_LLPREFERENCEFLOATER_H

View File

@ -861,7 +861,14 @@ bool idle_startup()
}
gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
// gDebugInfo["LoginName"] = userid;
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
if (gCrashSettings.getBOOL("CrashSubmitName"))
{
// Only include the agent name if the user consented
gDebugInfo["LoginName"] = userid;
}
// [/SL:KB]
// create necessary directories
// *FIX: these mkdir's should error check
@ -2931,7 +2938,14 @@ bool process_login_success_response()
// unpack login data needed by the application
text = response["agent_id"].asString();
if(!text.empty()) gAgentID.set(text);
gDebugInfo["AgentID"] = text;
// gDebugInfo["AgentID"] = text;
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
if (gCrashSettings.getBOOL("CrashSubmitName"))
{
// Only include the agent UUID if the user consented
gDebugInfo["AgentID"] = text;
}
// [/SL:KB]
// Agent id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.
@ -2939,7 +2953,7 @@ bool process_login_success_response()
text = response["session_id"].asString();
if(!text.empty()) gAgentSessionID.set(text);
gDebugInfo["SessionID"] = text;
// gDebugInfo["SessionID"] = text;
// Session id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.

View File

@ -147,6 +147,13 @@
layout="topleft"
help_topic="preferences_skins_tab"
name="skins" />
<panel
class="panel_preference_crashreports"
filename="panel_preferences_crashreports.xml"
label="Crash Reports"
layout="topleft"
help_topic="preferences_crashreports_tab"
name="crashreports" />
<panel
class="panel_preference_firestorm"
filename="panel_preferences_firestorm.xml"

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="true"
follows="left|top|right|bottom"
height="408"
label="Crash Reports"
layout="topleft"
left="102"
name="crash_reports"
top="1"
width="517">
<check_box
layout="topleft"
follows="top|left"
left="30"
top="30"
width="250"
height="16"
label="Send crash reports to catznip.com"
name="checkSendCrashReports"
parse_urls="false"
enabled="false"
/>
<text
layout="topleft"
follows="top|left"
left="80"
top_pad="15"
height="10"
width="90"
mouse_opaque="false"
type="string"
label="Logs:"
name="textSaveMiniDumpType"
>
Minidump Type :
</text>
<combo_box
layout="topleft"
follows="top|left"
top_pad="-15"
left_pad="10"
height="23"
width="125"
control_name="SaveMinidumpType"
name="comboSaveMiniDumpType"
enabled="false"
>
<combo_box.item
label="Minimal"
value="0" />
<combo_box.item
label="Default"
value="1" />
<combo_box.item
label="Extended"
value="2" />
</combo_box>
<check_box
layout="topleft"
follows="top|left"
left="60"
top_pad="7"
height="16"
label="Always ask before sending"
name="checkSendCrashReportsAlwaysAsk"
width="250"
enabled="false"
/>
<check_box
layout="topleft"
follows="top|left"
top_pad="5"
height="16"
label="Include settings.xml"
name="checkSendSettings"
width="130"
enabled="false"
/>
<text
name="textSendSettings"
follows="left|top"
layout="topleft"
top_pad="5"
left_delta="20"
height="20"
width="230"
text_color="White_25">
(contains Second Life name)
</text>
<check_box
layout="topleft"
follows="top|left"
left="60"
top_pad="0"
height="16"
label="Include Second Life name"
name="checkSendName"
width="160"
enabled="false"
/>
<text
name="textSendName"
follows="left|top"
layout="topleft"
top_pad="5"
left_delta="20"
height="20"
width="275"
text_color="White_25">
(used to ask for additional information if needed)
</text>
<text
layout="topleft"
follows="top|left"
left="30"
type="string"
length="1"
height="10"
mouse_opaque="false"
name="textInformation1"
top_pad="30"
width="475"
>
Unless checked above crash reports only contain information relevant to the crash.
</text>
<text
layout="topleft"
follows="top|left"
left="30"
type="string"
length="1"
height="10"
mouse_opaque="false"
name="textInformation2"
width="475"
>
Second Life logs are not sent, please review the contents and email separately
</text>
<text
layout="topleft"
follows="top|left"
left="30"
type="string"
length="1"
height="10"
mouse_opaque="false"
name="textInformation3"
width="475"
>
if you feel they might contain additional information.
</text>
<text
layout="topleft"
follows="top|left"
left="30"
type="string"
length="1"
height="10"
mouse_opaque="false"
name="textInformation4"
top_pad="20"
width="350"
font.style="BOLD"
>
Privacy policy: http://catznip.com/blog/privacy/
</text>
</panel>

View File

@ -25,12 +25,14 @@ include_directories(
set(win_crash_logger_SOURCE_FILES
win_crash_logger.cpp
llcrashloggerwindows.cpp
llcrashlookupwindows.cpp
)
set(win_crash_logger_HEADER_FILES
CMakeLists.txt
llcrashloggerwindows.h
llcrashlookupwindows.h
resource.h
StdAfx.h
win_crash_logger.h
@ -79,6 +81,7 @@ target_link_libraries(windows-crash-logger
ole32
oleaut32
Wldap32
dbgeng
)
if (WINDOWS)

View File

@ -29,6 +29,9 @@
#include "stdafx.h"
#include "resource.h"
#include "llcrashloggerwindows.h"
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
#include "llcrashlookupwindows.h"
// [/SL:KB]
#include <sstream>
@ -241,10 +244,16 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
LLCrashLoggerWindows::LLCrashLoggerWindows(void)
{
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
mCrashLookup = new LLCrashLookupWindows();
// [/SL:KB]
}
LLCrashLoggerWindows::~LLCrashLoggerWindows(void)
{
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
delete mCrashLookup;
// [/SL:KB]
}
bool LLCrashLoggerWindows::init(void)
@ -292,7 +301,10 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles()
SetCursor(gCursorWait);
// At this point we're responsive enough the user could click the close button
SetCursor(gCursorArrow);
mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo();
// mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo();
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-14 (Catznip-2.6.0a) | Added: Catznip-2.4.0a
mCrashInfo["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo();
// [/SL:KB]
}
bool LLCrashLoggerWindows::mainLoop()

View File

@ -0,0 +1,141 @@
/**
* @file llcrashlookupwindows.cpp
* @brief Basic Windows crash analysis
*
* Copyright (C) 2011, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "linden_common.h"
#include "stdafx.h"
#include "resource.h"
#include "llcrashlookupwindows.h"
#define MAX_STACK_FRAMES 64
LLCrashLookupWindows::LLCrashLookupWindows()
: LLCrashLookup()
, m_pDbgClient(NULL)
, m_pDbgControl(NULL)
, m_pDbgSymbols(NULL)
{
CoInitialize(NULL);
// Create the base IDebugClient object and then query it for the class instances we're interested in
HRESULT hRes = DebugCreate(__uuidof(IDebugClient), (void**)&m_pDbgClient);
if (SUCCEEDED(hRes))
{
hRes = m_pDbgClient->QueryInterface(__uuidof(IDebugControl4), (void**)&m_pDbgControl);
if (FAILED(hRes))
return;
hRes = m_pDbgClient->QueryInterface(__uuidof(IDebugSymbols2), (void**)&m_pDbgSymbols);
if (FAILED(hRes))
return;
}
}
LLCrashLookupWindows::~LLCrashLookupWindows()
{
if (m_pDbgSymbols)
{
m_pDbgSymbols->Release();
m_pDbgSymbols = NULL;
}
if (m_pDbgControl)
{
m_pDbgControl->Release();
m_pDbgControl = NULL;
}
if (m_pDbgClient)
{
m_pDbgClient->Release();
m_pDbgClient = NULL;
}
CoUninitialize();
}
bool LLCrashLookupWindows::initFromDump(const std::string& strDumpPath)
{
m_nInstructionAddr = m_nModuleBaseAddr = 0;
m_strModule.clear();
m_nModuleTimeStamp = m_nModuleChecksum = 0;
m_nModuleVersion = 0;
// Sanity check - make sure we have all the class instances
if ( (!m_pDbgClient) || (!m_pDbgControl) || (!m_pDbgSymbols) )
return false;
// Open the minidump and wait to finish processing
HRESULT hRes = m_pDbgClient->OpenDumpFile(strDumpPath.c_str());
if (FAILED(hRes))
return false;
m_pDbgControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
// Try to find an event that describes an exception
ULONG nEventType = 0, nProcessId = 0, nThreadId = 0;
BYTE bufContext[1024] = {0}; ULONG szContext = 0;
hRes = m_pDbgControl->GetStoredEventInformation(
&nEventType, &nProcessId, &nThreadId, bufContext, sizeof(bufContext), &szContext, NULL, 0, 0);
if ( (FAILED(hRes)) || (DEBUG_EVENT_EXCEPTION != nEventType) )
return false;
// Get the stack trace for the exception
DEBUG_STACK_FRAME dbgStackFrames[MAX_STACK_FRAMES]; ULONG cntStackFrames = 0;
BYTE* pbufStackFrameContexts = new BYTE[MAX_STACK_FRAMES * szContext];
hRes = m_pDbgControl->GetContextStackTrace(
bufContext, szContext, dbgStackFrames, ARRAYSIZE(dbgStackFrames),
pbufStackFrameContexts, MAX_STACK_FRAMES * szContext, szContext, &cntStackFrames);
if ( (FAILED(hRes)) || (cntStackFrames < 1) )
return false;
// Since the user won't have any debug symbols present we're really only interested in the top stack frame
m_nInstructionAddr = dbgStackFrames[0].InstructionOffset;
ULONG idxModule = 0;
hRes = m_pDbgSymbols->GetModuleByOffset(m_nInstructionAddr, 0, &idxModule, &m_nModuleBaseAddr);
if (FAILED(hRes))
return false;
// Lookup the name of the module where the crash occurred
CHAR strModule[MAX_PATH] = {0};
hRes = m_pDbgSymbols->GetModuleNameString(
DEBUG_MODNAME_MODULE, DEBUG_ANY_ID, m_nModuleBaseAddr, strModule, ARRAYSIZE(strModule) - 1, NULL);
if (FAILED(hRes))
return false;
m_strModule = strModule;
// Grab some basic properties we use for verification of the image
DEBUG_MODULE_PARAMETERS dbgModuleParams;
hRes = m_pDbgSymbols->GetModuleParameters(1, &m_nModuleBaseAddr, 0, &dbgModuleParams);
if ( (SUCCEEDED(hRes)) && (DEBUG_INVALID_OFFSET != dbgModuleParams.Base) )
{
m_nModuleTimeStamp = dbgModuleParams.TimeDateStamp;
m_nModuleChecksum = dbgModuleParams.Checksum;
}
// Grab the version number as well
BYTE bufVersionInfo[1024] = {0};
hRes = m_pDbgSymbols->GetModuleVersionInformation(DEBUG_ANY_ID, m_nModuleBaseAddr, "\\", bufVersionInfo, 1024, NULL);
if (SUCCEEDED(hRes))
{
VS_FIXEDFILEINFO* pFileInfo = (VS_FIXEDFILEINFO*)bufVersionInfo;
m_nModuleVersion = ((U64)pFileInfo->dwFileVersionMS << 32) + pFileInfo->dwFileVersionLS;
}
return true;
}

View File

@ -0,0 +1,44 @@
/**
* @file llcrashlookupwindows.h
* @brief Basic Windows crash analysis
*
* Copyright (C) 2011, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef LLCRASHLOOKUPWINDOWS_H
#define LLCRASHLOOKUPWINDOWS_H
#include <DbgEng.h>
#include "llcrashlookup.h"
class LLCrashLookupWindows : public LLCrashLookup
{
public:
LLCrashLookupWindows();
virtual ~LLCrashLookupWindows();
public:
/*virtual*/ bool initFromDump(const std::string& strDumpPath);
protected:
IDebugClient* m_pDbgClient;
IDebugControl4* m_pDbgControl;
IDebugSymbols2* m_pDbgSymbols;
};
#endif // LLCRASHLOOKUP_H

View File

@ -1,29 +1,3 @@
/**
* @file resource.h
* @brief Windows crash logger windows resources
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by win_crash_logger.rc

View File

@ -74,11 +74,11 @@ BEGIN
DEFPUSHBUTTON "Send",IDOK,198,104,45,15,WS_GROUP
PUSHBUTTON "Don't Send",IDCANCEL,247,104,45,15,WS_GROUP
LTEXT "%s appears to have crashed.",IDC_STATIC_HEADER,4,4,288,14
LTEXT "This crash reporter collects information about your computer's hardware, operating system, and some %s logs, which are used for debugging purposes only.",IDC_STATIC_WHATINFO,4,23,288,19,NOT WS_GROUP
LTEXT "This crash reporter collects information about your computer's hardware configuration and operating system which is used only for debugging purposes.\r\nSecondLife logs are not collected.",IDC_STATIC_WHATINFO,4,23,288,29,NOT WS_GROUP
CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,106,89,13
LTEXT "Sending crash reports is the best way to help us improve the quality of %s.",IDC_STATIC_MOTIVATION,4,43,288,8
LTEXT "If you continue to experience this problem, please try:",IDC_STATIC,4,57,251,8
LTEXT "- Contacting support by visiting http://www.phoenixviewer.com/support",IDC_STATIC,4,67,231,8
LTEXT "Sending crash reports is the best way to help us improve the quality of %s.",IDC_STATIC_MOTIVATION,4,54,288,8
CONTROL "This report will be sent to phoenixviewer.com, not Linden Lab.\r\nPlease review the privacy policy at http://<privacy-placeholder> for more information.",IDC_STATIC,
"Static",SS_LEFTNOWORDWRAP | WS_GROUP,4,68,288,17
END
IDD_PREVREPORTBOX DIALOGEX 100, 100, 232, 213
@ -92,13 +92,13 @@ BEGIN
PUSHBUTTON "Don't Send",IDCANCEL,181,193,45,15,WS_GROUP
LTEXT "%s appears to have crashed or frozen the last time it ran.",IDC_STATIC_HEADER,4,4,214,8
LTEXT "This crash reporter collects information about your computer's",IDC_STATIC,4,17,201,8
LTEXT "hardware configuration, operating system, and some %s",IDC_STATIC_MSG,4,25,212,8
LTEXT "logs, all of which are used for debugging purposes only.",IDC_STATIC,4,33,210,8
LTEXT "hardware configuration and operating system which is used only",IDC_STATIC_MSG,4,25,212,8
LTEXT "for debugging purposes. SecondLife logs are not collected.",IDC_STATIC,4,33,210,8
LTEXT "In the space below, please briefly describe what you were doing",IDC_STATIC,3,48,208,8
LTEXT "or trying to do just prior to the crash.",IDC_STATIC,3,56,204,8
LTEXT "If you don't wish to send a crash report, press Don't Send.",IDC_STATIC,3,90,223,8
LTEXT "This report is NOT read by customer support. If you have billing or",IDC_STATIC,3,68,208,8
LTEXT "other questions, please go to: www.phoenixviewer.com/support",IDC_STATIC,3,76,206,8
LTEXT "This report will be sent to phoenixviewer.com, not Linden Lab. Please review",IDC_STATIC,3,68,224,8
LTEXT "the privacy policy at <privacy-placeholder> for more information.",IDC_STATIC,3,76,226,8
CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,193,89,13
END