Breakpad: Commence nuclear bombardment of the unused stuff

Windows breakpad crash reports implemented and uploaded
TODO: llappviewer linux and mac port of breakpad3
This commit is contained in:
Latif Khalifa
2013-10-01 23:41:38 +02:00
parent 81fa147450
commit 98d7721ab2
44 changed files with 35 additions and 4718 deletions

View File

@@ -75,7 +75,6 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
@@ -87,28 +86,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
# add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
#endif (NOT LINUX)
if (LINUX)
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
add_dependencies(viewer linux-crash-logger-strip-target)
elseif (DARWIN)
#add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
#add_subdirectory(${VIEWER_PREFIX}mac_updater)
add_dependencies(viewer mac-crash-logger)
#add_dependencies(viewer mac-updater)
elseif (WINDOWS)
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
if (EXISTS ${VIEWER_DIR}win_setup)
add_subdirectory(${VIEWER_DIR}win_setup)
endif (EXISTS ${VIEWER_DIR}win_setup)
add_subdirectory(${VIEWER_PREFIX}win_updater)
add_dependencies(viewer windows-updater)
add_dependencies(viewer windows-crash-logger)
elseif (SOLARIS)
add_subdirectory(solaris_crash_logger)
add_dependencies(viewer solaris-crash-logger)
endif (LINUX)
add_subdirectory(${VIEWER_PREFIX}newview/statemachine)
add_subdirectory(${VIEWER_PREFIX}newview)
add_dependencies(viewer secondlife-bin)

View File

@@ -61,7 +61,6 @@ set(cmake_SOURCE_FILES
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
LLCrashLogger.cmake
LLImage.cmake
LLImageJ2COJ.cmake
LLInventory.cmake

View File

@@ -1,7 +0,0 @@
# -*- cmake -*-
set(LLCRASHLOGGER_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcrashlogger
)
set(LLCRASHLOGGER_LIBRARIES llcrashlogger)

View File

@@ -1,72 +0,0 @@
# -*- cmake -*-
project(linux_crash_logger)
include(00-Common)
include(LLCommon)
include(LLCrashLogger)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLXML)
include(Linking)
include(UI)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCRASHLOGGER_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(linux_crash_logger_SOURCE_FILES
linux_crash_logger.cpp
llcrashloggerlinux.cpp
)
set(linux_crash_logger_HEADER_FILES
CMakeLists.txt
llcrashloggerlinux.h
)
set_source_files_properties(${linux_crash_logger_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND linux_crash_logger_SOURCE_FILES
${linux_crash_logger_HEADER_FILES}
)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
target_link_libraries(linux-crash-logger
${LLCRASHLOGGER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLUI_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${UI_LIBRARIES}
${DB_LIBRARIES}
${XMLRPCEPI_LIBRARIES}
${CURL_LIBRARIES}
${APR_LIBRARIES}
${APRUTIL_LIBRARIES}
${CRYPTO_LIBRARIES}
rt
)
add_custom_command(
OUTPUT linux-crash-logger-stripped
COMMAND strip
ARGS --strip-debug -o linux-crash-logger-stripped linux-crash-logger
DEPENDS linux-crash-logger
)
add_custom_target(linux-crash-logger-strip-target ALL
DEPENDS linux-crash-logger-stripped)

View File

@@ -1,45 +0,0 @@
/**
* @file linux_crash_logger.cpp
* @brief Linux crash logger implementation
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "llcrashloggerlinux.h"
int main(int argc, char **argv)
{
LLCrashLoggerLinux app;
app.parseCommandOptions(argc, argv);
app.init();
app.mainLoop();
app.cleanup();
return 0;
}

View File

@@ -1,148 +0,0 @@
/**
* @file llcrashloggerlinux.cpp
* @brief Linux crash logger implementation
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "llcrashloggerlinux.h"
#include <iostream>
#include "linden_common.h"
#include "boost/tokenizer.hpp"
#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
#include "llerror.h"
#include "llfile.h"
#include "lltimer.h"
#include "llstring.h"
#include "lldir.h"
#include "llsdserialize.h"
#if LL_GTK
# include "gtk/gtk.h"
#endif // LL_GTK
#define MAX_LOADSTRING 100
// These need to be localized.
static const char dialog_text[] =
"Second Life appears to have crashed or frozen last time it ran.\n"
"This crash reporter collects information about your computer's hardware, operating system, and some Second Life logs, all of which are used for debugging purposes only.\n"
"\n"
"Send crash report?";
static const char dialog_title[] =
"Second Life Crash Logger";
#if LL_GTK
static void response_callback (GtkDialog *dialog,
gint arg1,
gpointer user_data)
{
gint *response = (gint*)user_data;
*response = arg1;
gtk_widget_destroy(GTK_WIDGET(dialog));
gtk_main_quit();
}
#endif // LL_GTK
static BOOL do_ask_dialog(void)
{
#if LL_GTK
gtk_disable_setlocale();
if (!gtk_init_check(NULL, NULL)) {
llinfos << "Could not initialize GTK for 'ask to send crash report' dialog; not sending report." << llendl;
return FALSE;
}
GtkWidget *win = NULL;
GtkDialogFlags flags = GTK_DIALOG_MODAL;
GtkMessageType messagetype = GTK_MESSAGE_QUESTION;
GtkButtonsType buttons = GTK_BUTTONS_YES_NO;
gint response = GTK_RESPONSE_NONE;
win = gtk_message_dialog_new(NULL,
flags, messagetype, buttons,
"%s", dialog_text);
gtk_window_set_type_hint(GTK_WINDOW(win),
GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_window_set_title(GTK_WINDOW(win), dialog_title);
g_signal_connect (win,
"response",
G_CALLBACK (response_callback),
&response);
gtk_widget_show_all (win);
gtk_main();
return (GTK_RESPONSE_OK == response ||
GTK_RESPONSE_YES == response ||
GTK_RESPONSE_APPLY == response);
#else
return FALSE;
#endif // LL_GTK
}
LLCrashLoggerLinux::LLCrashLoggerLinux(void)
{
}
LLCrashLoggerLinux::~LLCrashLoggerLinux(void)
{
}
void LLCrashLoggerLinux::gatherPlatformSpecificFiles()
{
mFileMap["CrashLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log").c_str();
}
bool LLCrashLoggerLinux::mainLoop()
{
bool send_logs = true;
if(CRASH_BEHAVIOR_ASK == getCrashBehavior())
{
send_logs = do_ask_dialog();
}
else if(CRASH_BEHAVIOR_NEVER_SEND == getCrashBehavior())
{
send_logs = false;
}
if(send_logs)
{
sendCrashLogs();
}
return true;
}
void LLCrashLoggerLinux::updateApplication(const std::string& message)
{
LLCrashLogger::updateApplication(message);
}

View File

@@ -1,50 +0,0 @@
/**
* @file llcrashloggerlinux.h
* @brief Linux crash logger definition
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
*/
#ifndef LLCRASHLOGGERLINUX_H
#define LLCRASHLOGGERLINUX_H
#include "linden_common.h"
#include "llcrashlogger.h"
#include "llstring.h"
class LLCrashLoggerLinux : public LLCrashLogger
{
public:
LLCrashLoggerLinux(void);
~LLCrashLoggerLinux(void);
virtual bool mainLoop();
virtual void updateApplication(const std::string& = LLStringUtil::null);
virtual void gatherPlatformSpecificFiles();
};
#endif

View File

@@ -1,38 +0,0 @@
# -*- cmake -*-
project(llcrashlogger)
include(00-Common)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(llcrashlogger_SOURCE_FILES
llcrashlogger.cpp
llcrashlock.cpp
)
set(llcrashlogger_HEADER_FILES
CMakeLists.txt
llcrashlogger.h
llcrashlock.h
)
set_source_files_properties(${llcrashlogger_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES})
add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES})
add_dependencies(llcrashlogger prepare)

View File

@@ -1,211 +0,0 @@
/**
* @file llformat.cpp
* @date January 2007
* @brief string formatting utility
*
* $LicenseInfo:firstyear=2007&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$
*/
#include "linden_common.h"
#include "llcrashlock.h"
#include "lldir.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llnametable.h"
#include "llframetimer.h"
#include <boost/filesystem.hpp>
#include <string>
#include <iostream>
#include <stdio.h>
#if LL_WINDOWS //For windows platform.
#include <windows.h>
#include <TlHelp32.h>
/*
namespace {
inline DWORD getpid() {
return GetCurrentProcessId();
}
}
*/
bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
{
std::wstring wpname;
wpname = std::wstring(pname.begin(), pname.end());
HANDLE snapshot;
PROCESSENTRY32 pe32;
bool matched = false;
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
{
return false;
}
else
{
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &pe32))
{
do {
std::wstring wexecname = pe32.szExeFile;
std::string execname = std::string(wexecname.begin(), wexecname.end());
if (!wpname.compare(pe32.szExeFile))
{
if (pid == (U32)pe32.th32ProcessID)
{
matched = true;
break;
}
}
} while (Process32Next(snapshot, &pe32));
}
}
CloseHandle(snapshot);
return matched;
}
#else //Everyone Else
bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
{
//Will boost.process ever become a reality?
std::stringstream cmd;
cmd << "pgrep '" << pname << "' | grep '^" << pid << "$'";
return (!system(cmd.str().c_str()));
}
#endif //Everyone else.
LLCrashLock::LLCrashLock() : mCleanUp(true), mWaitingPID(0)
{
}
void LLCrashLock::setCleanUp(bool cleanup)
{
mCleanUp = cleanup; //Allow cleanup to be disabled for debugging.
}
LLSD LLCrashLock::getLockFile(std::string filename)
{
LLSD lock_sd = LLSD::emptyMap();
llifstream ifile(filename);
if (ifile.is_open())
{
LLSDSerialize::fromXML(lock_sd, ifile);
ifile.close();
}
return lock_sd;
}
bool LLCrashLock::putLockFile(std::string filename, const LLSD& data)
{
bool result = true;
llofstream ofile(filename);
if (!LLSDSerialize::toXML(data,ofile))
{
result=false;
}
ofile.close();
return result;
}
bool LLCrashLock::requestMaster( F32 timeout )
{
if (mMaster.empty())
{
mMaster = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"crash_master.lock");
}
LLSD lock_sd=getLockFile(mMaster);
if (lock_sd.has("pid"))
{
mWaitingPID = lock_sd["pid"].asInteger();
if ( isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()) )
{
mTimer.resetWithExpiry(timeout);
return false;
}
}
U32 pid = getpid();
lock_sd["pid"] = (LLSD::Integer)pid;
return putLockFile(mMaster,lock_sd);
}
bool LLCrashLock::checkMaster()
{
if (mWaitingPID)
{
return (!isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()));
}
return false;
}
bool LLCrashLock::isWaiting()
{
return !mTimer.hasExpired();
}
void LLCrashLock::releaseMaster()
{
//Yeeeeeeehaw
unlink(mMaster.c_str());
}
LLSD LLCrashLock::getProcessList()
{
if (mDumpTable.empty())
{
mDumpTable= gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"crash_table.lock");
}
return getLockFile(mDumpTable);
}
//static
bool LLCrashLock::fileExists(std::string filename)
{
return boost::filesystem::exists(filename.c_str());
}
void LLCrashLock::cleanupProcess(std::string proc_dir)
{
boost::filesystem::remove_all(proc_dir);
}
bool LLCrashLock::putProcessList(const LLSD& proc_sd)
{
return putLockFile(mDumpTable,proc_sd);
}

View File

@@ -1,73 +0,0 @@
/**
* @file llpidlock.h
* @brief Maintainence of disk locking files for crash reporting
*
* $LicenseInfo:firstyear=2001&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$
*/
#ifndef LL_CRASHLOCK_H
#define LL_CRASHLOCK_H
#include "llframetimer.h"
class LLSD;
#if !LL_WINDOWS //For non-windows platforms.
#include <signal.h>
#endif
//Crash reporter will now be kicked off by the viewer but otherwise
//run independent of the viewer.
class LLCrashLock
{
public:
LLCrashLock();
bool requestMaster( F32 timeout=300.0); //Wait until timeout for master lock.
bool checkMaster(); //True if available. False if not.
void releaseMaster( ); //Release master lockfile.
bool isLockPresent(std::string filename); //Check if lockfile exists.
bool isProcessAlive(U32 pid, const std::string& pname); //Check if pid is alive.
bool isWaiting(); //Waiting for master lock to be released.
LLSD getProcessList(); //Get next process pid/dir pairs
void cleanupProcess(std::string proc_dir); //Remove from list, clean up working dir.
bool putProcessList(const LLSD& processlist); //Write pid/dir pairs back to disk.
static bool fileExists(std::string filename);
//getters
S32 getPID();
//setters
void setCleanUp(bool cleanup=true);
void setSaveName(std::string savename);
private:
LLSD getLockFile(std::string filename);
bool putLockFile(std::string filename, const LLSD& data);
bool mCleanUp;
std::string mMaster;
std::string mDumpTable;
U32 mWaitingPID; //The process we're waiting on if any.
LLFrameTimer mTimer;
};
#endif // LL_CRASHLOCK_H

View File

@@ -1,76 +0,0 @@
# -*- cmake -*-
project(mac_crash_logger)
include(00-Common)
include(LLCommon)
include(LLCrashLogger)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLXML)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCRASHLOGGER_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
set(mac_crash_logger_SOURCE_FILES
mac_crash_logger.cpp
llcrashloggermac.cpp
)
set(mac_crash_logger_HEADER_FILES
CMakeLists.txt
llcrashloggermac.h
)
set_source_files_properties(${mac_crash_logger_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_HEADER_FILES})
set(mac_crash_logger_RESOURCE_FILES
CrashReporter.nib/
)
set_source_files_properties(
${mac_crash_logger_RESOURCE_FILES}
PROPERTIES
HEADER_FILE_ONLY TRUE
)
SOURCE_GROUP("Resources" FILES ${mac_crash_logger_RESOURCE_FILES})
list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES})
add_executable(mac-crash-logger
MACOSX_BUNDLE
${mac_crash_logger_SOURCE_FILES})
set_target_properties(mac-crash-logger
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
target_link_libraries(mac-crash-logger
${LLCRASHLOGGER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
add_custom_command(
TARGET mac-crash-logger POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS
-E
copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/CrashReporter.nib
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-crash-logger.app/Contents/Resources/CrashReporter.nib
)

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBFramework Version</key>
<string>629</string>
<key>IBLastKnownRelativeProjectPath</key>
<string>../../build-darwin-i386/SecondLife.xcodeproj</string>
<key>IBOldestOS</key>
<integer>5</integer>
<key>IBOpenObjects</key>
<array/>
<key>IBSystem Version</key>
<string>9E17</string>
<key>targetFramework</key>
<string>IBCarbonFramework</string>
</dict>
</plist>

View File

@@ -1,68 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<object class="NSIBObjectData">
<object name="rootObject" class="NSCustomObject" id="1">
</object>
<array count="7" name="allObjects">
<object class="IBCarbonButton" id="182">
<ostype name="command">ok </ostype>
<string name="title">Send Report</string>
<string name="bounds">414 273 434 378 </string>
</object>
<object class="IBCarbonButton" id="183">
<ostype name="command">not!</ostype>
<int name="buttonType">2</int>
<string name="title">Don&apos;t Send</string>
<string name="bounds">414 390 434 487 </string>
</object>
<object class="IBCarbonStaticText" id="181">
<string name="title">Second Life appears to have crashed or frozen the last time it ran.&#10;&#10;This crash reporter collects information about your computer&apos;s hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only.&#10;&#10;In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help!&#10;&#10;This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/&#10;&#10;If you don&apos;t wish to send Linden Lab a crash report, press Cancel.&#10;</string>
<string name="bounds">20 20 231 487 </string>
</object>
<object class="IBCarbonWindow" id="166">
<int name="carbonWindowClass">2</int>
<int name="themeBrush">3</int>
<int name="windowPosition">7</int>
<string name="title">Second Life Crash Logger</string>
<object name="rootControl" class="IBCarbonRootControl" id="167">
<array count="5" name="subviews">
<reference idRef="181"/>
<reference idRef="182"/>
<reference idRef="183"/>
<object class="IBCarbonEditText" id="185">
<ostype name="controlSignature">text</ostype>
<boolean name="isUnicode">TRUE</boolean>
<string name="bounds">242 23 391 484 </string>
</object>
<object class="IBCarbonCheckBox" id="193">
<ostype name="controlSignature">remb</ostype>
<string name="title">Remember This Choice</string>
<string name="bounds">415 20 433 186 </string>
</object>
</array>
<string name="bounds">0 0 454 507 </string>
</object>
<string name="windowRect">257 653 711 1160 </string>
<string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
</object>
<reference idRef="185"/>
<reference idRef="167"/>
<reference idRef="193"/>
</array>
<array count="7" name="allParents">
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="1"/>
<reference idRef="167"/>
<reference idRef="166"/>
<reference idRef="167"/>
</array>
<dictionary count="2" name="nameTable">
<string>CrashReporter</string>
<reference idRef="166"/>
<string>File&apos;s Owner</string>
<reference idRef="1"/>
</dictionary>
<string name="targetFramework">IBCarbonFramework</string>
<unsigned_int name="nextObjectID">194</unsigned_int>
</object>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>mac-crash-logger</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.secondlife.indra.crashreporter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string></string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

View File

@@ -1,345 +0,0 @@
/**
* @file llcrashloggermac.cpp
* @brief Mac OSX crash logger implementation
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "llcrashloggermac.h"
#include <Carbon/Carbon.h>
#include <iostream>
#include <sstream>
#include "boost/tokenizer.hpp"
#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
#include "llerror.h"
#include "llfile.h"
#include "lltimer.h"
#include "llstring.h"
#include "lldir.h"
#include "llsdserialize.h"
#define MAX_LOADSTRING 100
const char* const SETTINGS_FILE_HEADER = "version";
const S32 SETTINGS_FILE_VERSION = 101;
// Windows Message Handlers
BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog?
LLFILE *gDebugFile = NULL;
WindowRef gWindow = NULL;
EventHandlerRef gEventHandler = NULL;
std::string gUserNotes = "";
bool gSendReport = false;
bool gRememberChoice = false;
IBNibRef nib = NULL;
OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
{
OSStatus result = eventNotHandledErr;
OSStatus err;
UInt32 evtClass = GetEventClass(event);
UInt32 evtKind = GetEventKind(event);
if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
{
HICommand cmd;
err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
if(err == noErr)
{
//Get the value of the checkbox
ControlID id;
ControlRef checkBox = NULL;
id.signature = 'remb';
id.id = 0;
err = GetControlByID(gWindow, &id, &checkBox);
if(err == noErr)
{
if(GetControl32BitValue(checkBox) == kControlCheckBoxCheckedValue)
{
gRememberChoice = true;
}
else
{
gRememberChoice = false;
}
}
switch(cmd.commandID)
{
case kHICommandOK:
{
char buffer[65535]; /* Flawfinder: ignore */
Size size = sizeof(buffer) - 1;
ControlRef textField = NULL;
id.signature = 'text';
id.id = 0;
err = GetControlByID(gWindow, &id, &textField);
if(err == noErr)
{
// Get the user response text
err = GetControlData(textField, kControlNoPart, kControlEditTextTextTag, size, (Ptr)buffer, &size);
}
if(err == noErr)
{
// Make sure the string is terminated.
buffer[size] = 0;
gUserNotes = buffer;
llinfos << buffer << llendl;
}
// Send the report.
QuitAppModalLoopForWindow(gWindow);
gSendReport = true;
result = noErr;
}
break;
case kHICommandCancel:
QuitAppModalLoopForWindow(gWindow);
result = noErr;
break;
default:
result = eventNotHandledErr;
}
}
}
return(result);
}
LLCrashLoggerMac::LLCrashLoggerMac(void)
{
}
LLCrashLoggerMac::~LLCrashLoggerMac(void)
{
}
bool LLCrashLoggerMac::init(void)
{
bool ok = LLCrashLogger::init();
if(!ok) return false;
if(mCrashBehavior != CRASH_BEHAVIOR_ASK) return true;
// Real UI...
OSStatus err;
err = CreateNibReference(CFSTR("CrashReporter"), &nib);
if(err == noErr)
{
err = CreateWindowFromNib(nib, CFSTR("CrashReporter"), &gWindow);
}
if(err == noErr)
{
// Set focus to the edit text area
ControlRef textField = NULL;
ControlID id;
id.signature = 'text';
id.id = 0;
// Don't set err if any of this fails, since it's non-critical.
if(GetControlByID(gWindow, &id, &textField) == noErr)
{
SetKeyboardFocus(gWindow, textField, kControlFocusNextPart);
}
}
if(err == noErr)
{
ShowWindow(gWindow);
}
if(err == noErr)
{
// Set up an event handler for the window.
EventTypeSpec handlerEvents[] =
{
{ kEventClassCommand, kEventCommandProcess }
};
InstallWindowEventHandler(
gWindow,
NewEventHandlerUPP(dialogHandler),
GetEventTypeCount (handlerEvents),
handlerEvents,
0,
&gEventHandler);
}
return true;
}
void LLCrashLoggerMac::gatherPlatformSpecificFiles()
{
updateApplication("Gathering hardware information...");
char path[MAX_PATH];
FSRef folder;
if(FSFindFolder(kUserDomain, kLogsFolderType, false, &folder) == noErr)
{
// folder is an FSRef to ~/Library/Logs/
if(FSRefMakePath(&folder, (UInt8*)&path, sizeof(path)) == noErr)
{
struct stat dw_stat;
std::string mBuf;
bool isLeopard = false;
// Try the 10.3 path first...
std::string dw_file_name = std::string(path) + std::string("/CrashReporter/Second Life.crash.log");
int res = stat(dw_file_name.c_str(), &dw_stat);
if (res)
{
// Try the 10.2 one next...
dw_file_name = std::string(path) + std::string("/Second Life.crash.log");
res = stat(dw_file_name.c_str(), &dw_stat);
}
if(res)
{
//10.5: Like 10.3+, except it puts the crash time in the file instead of dividing it up
//using asterisks. Get a directory listing, search for files starting with second life,
//use the last one found.
std::string old_file_name, current_file_name, pathname, mask;
pathname = std::string(path) + std::string("/CrashReporter/");
mask = "Second Life*";
while(gDirUtilp->getNextFileInDir(pathname, mask, current_file_name, false))
{
old_file_name = current_file_name;
}
if(old_file_name != "")
{
dw_file_name = pathname + old_file_name;
res=stat(dw_file_name.c_str(), &dw_stat);
isLeopard = true;
}
}
if (!res)
{
std::ifstream fp(dw_file_name.c_str());
std::stringstream str;
if(!fp.is_open()) return;
str << fp.rdbuf();
mBuf = str.str();
if(!isLeopard)
{
// Crash logs consist of a number of entries, one per crash.
// Each entry is preceeded by "**********" on a line by itself.
// We want only the most recent (i.e. last) one.
const char *sep = "**********";
const char *start = mBuf.c_str();
const char *cur = start;
const char *temp = strstr(cur, sep);
while(temp != NULL)
{
// Skip past the marker we just found
cur = temp + strlen(sep); /* Flawfinder: ignore */
// and try to find another
temp = strstr(cur, sep);
}
// If there's more than one entry in the log file, strip all but the last one.
if(cur != start)
{
mBuf.erase(0, cur - start);
}
}
mCrashInfo["CrashLog"] = mBuf;
}
else
{
llwarns << "Couldn't find any CrashReporter files..." << llendl;
}
}
}
}
bool LLCrashLoggerMac::mainLoop()
{
OSStatus err = noErr;
if(err == noErr && mCrashBehavior == CRASH_BEHAVIOR_ASK)
{
RunAppModalLoopForWindow(gWindow);
}
else if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
{
gSendReport = true;
}
if(gRememberChoice)
{
if(gSendReport) saveCrashBehaviorSetting(CRASH_BEHAVIOR_ALWAYS_SEND);
else saveCrashBehaviorSetting(CRASH_BEHAVIOR_NEVER_SEND);
}
if(gSendReport)
{
setUserText(gUserNotes);
sendCrashLogs();
}
if(gWindow != NULL)
{
DisposeWindow(gWindow);
}
if(nib != NULL)
{
DisposeNibReference(nib);
}
return true;
}
void LLCrashLoggerMac::updateApplication(const std::string& message)
{
LLCrashLogger::updateApplication();
}
bool LLCrashLoggerMac::cleanup()
{
return true;
}

View File

@@ -1,52 +0,0 @@
/**
* @file llcrashloggermac.h
* @brief Mac OSX crash logger definition
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
*/
#ifndef LLCRASHLOGGERMAC_H
#define LLCRASHLOGGERMAC_H
#include "linden_common.h"
#include "llcrashlogger.h"
#include "llstring.h"
class LLCrashLoggerMac : public LLCrashLogger
{
public:
LLCrashLoggerMac(void);
~LLCrashLoggerMac(void);
virtual bool init();
virtual bool mainLoop();
virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool cleanup();
virtual void gatherPlatformSpecificFiles();
};
#endif

View File

@@ -1,52 +0,0 @@
/**
* @file mac_crash_logger.cpp
* @brief Mac OSX crash logger implementation
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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 "linden_common.h"
#include "llcrashloggermac.h"
int main(int argc, char **argv)
{
//time(&gLaunchTime);
llinfos << "Starting Second Life Viewer Crash Reporter" << llendl;
LLCrashLoggerMac app;
app.parseCommandOptions(argc, argv);
if(!app.init())
{
return 0;
}
app.mainLoop();
return 0;
}

View File

@@ -1,4 +0,0 @@
{
IBClasses = ();
IBVersion = 1;
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>103 138 356 240 0 0 1280 1002 </string>
<key>IBFramework Version</key>
<string>362.0</string>
<key>IBSystem Version</key>
<string>7D24</string>
<key>targetFramework</key>
<string>IBCarbonFramework</string>
</dict>
</plist>

View File

@@ -1,56 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<object class="NSIBObjectData">
<string name="targetFramework">IBCarbonFramework</string>
<object name="rootObject" class="NSCustomObject" id="1">
<string name="customClass">NSApplication</string>
</object>
<array count="5" name="allObjects">
<object class="IBCarbonWindow" id="166">
<string name="windowRect">405 222 533 663 </string>
<string name="title">Second Life Updater</string>
<object name="rootControl" class="IBCarbonRootControl" id="167">
<string name="bounds">0 0 128 441 </string>
<array count="3" name="subviews">
<object class="IBCarbonStaticText" id="181">
<string name="bounds">20 20 44 421 </string>
<ostype name="controlSignature">what</ostype>
<string name="title">Initializing…</string>
</object>
<object class="IBCarbonButton" id="183">
<string name="bounds">88 351 108 421 </string>
<string name="title">Cancel</string>
<ostype name="command">not!</ostype>
<int name="buttonType">2</int>
</object>
<object class="IBCarbonProgressBar" id="193">
<string name="bounds">51 19 70 422 </string>
<ostype name="controlSignature">prog</ostype>
<int name="initialValue">50</int>
</object>
</array>
</object>
<boolean name="isResizable">FALSE</boolean>
<int name="carbonWindowClass">2</int>
<int name="themeBrush">3</int>
<int name="windowPosition">7</int>
</object>
<reference idRef="167"/>
<reference idRef="181"/>
<reference idRef="183"/>
<reference idRef="193"/>
</array>
<array count="5" name="allParents">
<reference idRef="1"/>
<reference idRef="166"/>
<reference idRef="167"/>
<reference idRef="167"/>
<reference idRef="167"/>
</array>
<dictionary count="2" name="nameTable">
<string>File&apos;s Owner</string>
<reference idRef="1"/>
<string>Updater</string>
<reference idRef="166"/>
</dictionary>
<unsigned_int name="nextObjectID">194</unsigned_int>
</object>

View File

@@ -1,66 +0,0 @@
# -*- cmake -*-
project(mac_updater)
include(00-Common)
include(CURL)
include(LLCommon)
include(LLVFS)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
)
set(mac_updater_SOURCE_FILES
mac_updater.cpp
)
set(mac_updater_HEADER_FILES
CMakeLists.txt
)
set_source_files_properties(${mac_updater_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND mac_updater_SOURCE_FILES ${mac_updater_HEADER_FILES})
set(mac_updater_RESOURCE_FILES
AutoUpdater.nib/
)
set_source_files_properties(
${mac_updater_RESOURCE_FILES}
PROPERTIES
HEADER_FILE_ONLY TRUE
)
SOURCE_GROUP("Resources" FILES ${mac_updater_RESOURCE_FILES})
list(APPEND mac_updater_SOURCE_FILES ${mac_updater_RESOURCE_FILES})
add_executable(mac-updater
MACOSX_BUNDLE
${mac_updater_SOURCE_FILES})
set_target_properties(mac-updater
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
target_link_libraries(mac-updater
${LLVFS_LIBRARIES}
${CURL_LIBRARIES}
${OPENSSL_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
add_custom_command(
TARGET mac-updater POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS
-E
copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdater.nib
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-updater.app/Contents/Resources/AutoUpdater.nib
)

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>mac-updater</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.secondlife.indra.autoupdater</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string></string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

File diff suppressed because it is too large Load Diff

View File

@@ -140,6 +140,7 @@ set(viewer_SOURCE_FILES
llcompilequeue.cpp
llconfirmationmanager.cpp
llconsole.cpp
llcrashlogger.cpp
llcurrencyuimanager.cpp
llcylinder.cpp
lldaycyclemanager.cpp
@@ -656,6 +657,7 @@ set(viewer_HEADER_FILES
llcompilequeue.h
llconfirmationmanager.h
llconsole.h
llcrashlogger.h
llcurrencyuimanager.h
llcylinder.h
lldaycyclemanager.h
@@ -1532,7 +1534,6 @@ if (WINDOWS)
if (PACKAGE)
add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
add_dependencies(package windows-updater windows-crash-logger)
endif (PACKAGE)
endif (WINDOWS)
@@ -1684,7 +1685,6 @@ if (DARWIN)
if (PACKAGE)
add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME})
add_dependencies(package mac-updater mac-crash-logger)
add_custom_command(
TARGET package POST_BUILD

View File

@@ -2199,7 +2199,7 @@ This should be as low as possible, but too low may break functionality</string>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
<string>http://crash.singularityviewer.org/submit.php</string>>
</map>
<key>AFKTimeout</key>
<map>

View File

@@ -86,7 +86,7 @@
#include "llvocache.h"
#include "llvopartgroup.h"
#include "llfloaterteleporthistory.h"
#include "llcrashlogger.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
@@ -640,6 +640,10 @@ bool LLAppViewer::init()
initMaxHeapSize() ;
LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ;
// Check if we have a crash report to send
LLCrashLogger crashLogger;
crashLogger.checkCrashDump();
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
mDumpPath = logdir;

View File

@@ -23,13 +23,9 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <map>
#include "llviewerprecompiledheaders.h"
#include "llcrashlogger.h"
#include "llcrashlock.h"
#include "linden_common.h"
#include "llstring.h"
#include "indra_constants.h" // CRASH_BEHAVIOR_...
@@ -46,12 +42,6 @@
#include "llproxy.h"
#include "aistatemachine.h"
LLPumpIO* gServicePump;
BOOL gBreak = false;
BOOL gSent = false;
extern void startEngineThread(void);
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout;
@@ -64,13 +54,12 @@ public:
virtual void error(U32 status, const std::string& reason)
{
gBreak = true;
llwarns << "Crash report sending failed: " << reason << llendl;
}
virtual void result(const LLSD& content)
{
gBreak = true;
gSent = true;
llinfos << "Crash report successfully sent" << llendl;
}
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const
@@ -88,7 +77,6 @@ LLCrashLogger::LLCrashLogger() :
mCrashBehavior(CRASH_BEHAVIOR_ALWAYS_SEND),
mCrashInPreviousExec(false),
mCrashSettings("CrashSettings"),
mSentCrashLogs(false),
mCrashHost("")
{
}
@@ -250,32 +238,6 @@ 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";
}
// 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";
mCrashInfo["DebugLog"] = mDebugLog;
mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log");
@@ -354,80 +316,15 @@ LLSD LLCrashLogger::constructPostData()
return mCrashInfo;
}
// Singu Note, defiend in indra_constants.h # const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
S32 LLCrashLogger::loadCrashBehaviorSetting()
{
// First check user_settings (in the user's home dir)
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
if (! mCrashSettings.loadFromFile(filename))
{
// Next check app_settings (in the SL program dir)
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, CRASH_SETTINGS_FILE);
mCrashSettings.loadFromFile(filename);
}
// If we didn't load any files above, this will return the default
S32 value = mCrashSettings.getS32("CrashSubmitBehavior");
// Whatever value we got, make sure it's valid
switch (value)
{
case CRASH_BEHAVIOR_NEVER_SEND:
return CRASH_BEHAVIOR_NEVER_SEND;
case CRASH_BEHAVIOR_ALWAYS_SEND:
return CRASH_BEHAVIOR_ALWAYS_SEND;
}
return CRASH_BEHAVIOR_ASK;
}
bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
{
switch (crash_behavior)
{
case CRASH_BEHAVIOR_ASK:
case CRASH_BEHAVIOR_NEVER_SEND:
case CRASH_BEHAVIOR_ALWAYS_SEND:
break;
default:
return false;
}
mCrashSettings.setS32("CrashSubmitBehavior", crash_behavior);
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
mCrashSettings.saveToFile(filename, FALSE);
return true;
}
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());
while(!gBreak)
{
updateApplication(); // No new message, just pump the IO
}
if(gSent)
{
return gSent;
}
}
return gSent;
}
bool LLCrashLogger::sendCrashLog(std::string dump_dir)
{
gDirUtilp->setDumpDir( dump_dir );
std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLifeCrashReport");
"SingularityCrashReport");
std::string report_file = dump_path + ".log";
gatherFiles();
LLSD post_data;
@@ -438,176 +335,30 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir)
std::ofstream out_file(report_file.c_str());
LLSDSerialize::toPrettyXML(post_data, out_file);
out_file.close();
bool sent = false;
//*TODO: Translate
if(mCrashHost != "")
{
sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), 3, 5);
}
if(!sent)
{
sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5);
}
mSentCrashLogs = sent;
return sent;
}
bool LLCrashLogger::sendCrashLogs()
{
LLHTTPClient::post(mCrashHost, post_data, new LLCrashLoggerResponder());
//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") )
{
rec["pid"]=opts["pid"];
rec["dumpdir"]=opts["dumpdir"];
rec["procname"]=opts["procname"];
#if LL_WINDOWS
locks.append(rec);
#endif
}
if (locks.isArray())
{
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");
mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
}
}
}
}
else
{
llwarns << "Discarding corrupted entry from lock table." << llendl;
}
}
}
#if !LL_WINDOWS
if (rec)
{
newlocks.append(rec);
}
#endif
mKeyMaster.putProcessList(newlocks);
return true;
}
void LLCrashLogger::updateApplication(const std::string& message)
{
/* Sing TODO
gServicePump->pump();
gServicePump->callback();
*/
if (!message.empty()) llinfos << message << llendl;
}
bool LLCrashLogger::init()
{
LLCurl::initCurl();
AIEngine::setMaxCount(100);
// We assume that all the logs we're looking for reside on the current drive
gDirUtilp->initAppDirs("SecondLife");
LLError::initForApplication(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
// Default to the product name "Second Life" (this is overridden by the -name argument)
mProductName = "Second Life";
// Handle locking
bool locked = mKeyMaster.requestMaster(); //Request maser locking file. wait time is defaulted to 300S
while (!locked && mKeyMaster.isWaiting())
{
#if LL_WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
locked = mKeyMaster.checkMaster();
}
if (!locked)
{
llwarns << "Unable to get master lock. Another crash reporter may be hung." << llendl;
return false;
}
// Rename current log file to ".old"
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
#if LL_WINDOWS
LLAPRFile::remove(old_log_file);
#endif
LLFile::rename(log_file.c_str(), old_log_file.c_str());
// Set the log file to crashreport.log
LLError::logToFile(log_file);
mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
"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();
// 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;
}
AICurlInterface::startCurlThread(&mCrashSettings);
startEngineThread();
/* Singu Note: not needed for AICurl
gServicePump = new LLPumpIO(gAPRPoolp);
gServicePump->prime(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
*/
return true;
}
// For cleanup code common to all platforms.
void LLCrashLogger::commonCleanup()
void LLCrashLogger::updateApplication(const std::string& message)
{
LLProxy::cleanupClass();
if (!message.empty()) llinfos << message << llendl;
}
void LLCrashLogger::checkCrashDump()
{
mCrashHost = gSavedSettings.getString("CrashHostUrl");
std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug";
if (gDirUtilp->fileExists(dumpDir))
{
sendCrashLog(dumpDir);
gDirUtilp->deleteDirAndContents(dumpDir);
}
else
{
llinfos << "No crash dump found frome previous run, not sending report" << LL_ENDL;
}
}

View File

@@ -33,9 +33,8 @@
#include "llapp.h"
#include "llsd.h"
#include "llcontrol.h"
#include "llcrashlock.h"
class LLCrashLogger : public LLApp
class LLCrashLogger
{
public:
LLCrashLogger();
@@ -48,17 +47,12 @@ public:
virtual void gatherPlatformSpecificFiles() {}
bool saveCrashBehaviorSetting(S32 crash_behavior);
bool sendCrashLog(std::string dump_dir);
bool sendCrashLogs();
LLSD constructPostData();
virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool init();
virtual bool mainLoop() = 0;
virtual bool cleanup() = 0;
void commonCleanup();
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);
bool readMinidump(std::string minidump_path);
void checkCrashDump();
protected:
S32 mCrashBehavior;
@@ -69,10 +63,7 @@ protected:
std::string mProductName;
LLSD mCrashInfo;
std::string mCrashHost;
std::string mAltCrashHost;
LLSD mDebugLog;
bool mSentCrashLogs;
LLCrashLock mKeyMaster;
};
#endif //LLCRASHLOGGER_H

View File

@@ -339,10 +339,6 @@ class WindowsManifest(ViewerManifest):
self.path(path_pair[1])
self.end_prefix()
# pull in the crash logger and updater from other projects
self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], dst="win_crash_logger.exe")
self.path(src='../win_updater/%s/windows-updater.exe' % self.args['configuration'], dst="updater.exe")
def nsi_file_commands(self, install=True):
def wpath(path):
@@ -545,18 +541,10 @@ class DarwinManifest(ViewerManifest):
print "Skipping libfmodex.dylib - not found"
pass
# our apps
try:
self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
except:
pass
# plugin launcher
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app")
# dependencies on shared libs
mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources")
slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources")
for libfile in ("libllcommon.dylib",
"libapr-1.0.dylib",
@@ -717,10 +705,8 @@ class LinuxManifest(ViewerManifest):
if self.buildtype().lower()=='release':
self.path("secondlife-stripped","bin/"+self.binary_name())
self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin")
else:
self.path("secondlife-bin","bin/"+self.binary_name())
self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
if self.prefix("res-sdl"):

View File

@@ -1,101 +0,0 @@
# -*- cmake -*-
project(win_crash_logger)
include(00-Common)
include(LLCommon)
include(LLCrashLogger)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLWindow)
include(LLXML)
include(Linking)
include(LLSharedLibs)
include(GoogleBreakpad)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCRASHLOGGER_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${BREAKPAD_INCLUDE_DIRECTORIES}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
)
set(win_crash_logger_SOURCE_FILES
win_crash_logger.cpp
llcrashloggerwindows.cpp
)
set(win_crash_logger_HEADER_FILES
CMakeLists.txt
llcrashloggerwindows.h
resource.h
StdAfx.h
win_crash_logger.h
)
set_source_files_properties(${win_crash_logger_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
set(win_crash_logger_RESOURCE_FILES
ll_icon.ico
)
set_source_files_properties(${win_crash_logger_RESOURCE_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
set(win_crash_logger_RESOURCE_FILES
win_crash_logger.rc
${win_crash_logger_RESOURCE_FILES}
)
SOURCE_GROUP("Resource Files" FILES ${win_crash_logger_RESOURCE_FILES})
list(APPEND
win_crash_logger_SOURCE_FILES
${win_crash_logger_HEADER_FILES}
${win_crash_logger_RESOURCE_FILES}
)
# find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES})
target_link_libraries(windows-crash-logger
${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
${LLCRASHLOGGER_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${WINDOWS_LIBRARIES}
# ${DXGUID_LIBRARY}
${GOOGLE_PERFTOOLS_LIBRARIES}
user32
gdi32
ole32
oleaut32
wininet
Wldap32
)
if (WINDOWS)
set_target_properties(windows-crash-logger
PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
)
endif (WINDOWS)
# Singu Note: not used by our build
# ll_deploy_sharedlibs_command(windows-crash-logger)

View File

@@ -1,34 +0,0 @@
/**
* @file StdAfx.cpp
* @brief windows crash logger source file for includes
*
* $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$
*/
// stdafx.cpp : source file that includes just the standard includes
// win_crash_logger.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@@ -1,56 +0,0 @@
/**
* @file StdAfx.h
* @brief standard system includes
*
* $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$
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
// Local Header Files
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,548 +0,0 @@
/**
* @file llcrashloggerwindows.cpp
* @brief Windows crash logger implementation
*
* $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$
*/
#include "linden_common.h"
#include "stdafx.h"
#include "resource.h"
#include "llcrashloggerwindows.h"
#include <sstream>
#include "boost/tokenizer.hpp"
#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
#include "llerror.h"
#include "llfile.h"
#include "lltimer.h"
#include "llstring.h"
#include "lldxhardware.h"
#include "lldir.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include <client/windows/crash_generation/crash_generation_server.h>
#include <client/windows/crash_generation/client_info.h>
#define MAX_LOADSTRING 100
#define MAX_STRING 2048
const char* const SETTINGS_FILE_HEADER = "version";
const S32 SETTINGS_FILE_VERSION = 101;
// Windows Message Handlers
// Global Variables:
HINSTANCE hInst= NULL; // current instance
TCHAR szTitle[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text
std::string gProductName;
HWND gHwndReport = NULL; // Send/Don't Send dialog
HWND gHwndProgress = NULL; // Progress window
HCURSOR gCursorArrow = NULL;
HCURSOR gCursorWait = NULL;
BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog?
std::stringstream gDXInfo;
bool gSendLogs = false;
LLCrashLoggerWindows* LLCrashLoggerWindows::sInstance = NULL;
//Conversion from char* to wchar*
//Replacement for ATL macros, doesn't allocate memory
//For more info see: http://www.codeguru.com/forum/showthread.php?t=337247
void ConvertLPCSTRToLPWSTR (const char* pCstring, WCHAR* outStr)
{
if (pCstring != NULL)
{
int nInputStrLen = strlen (pCstring);
// Double NULL Termination
int nOutputStrLen = MultiByteToWideChar(CP_ACP, 0, pCstring, nInputStrLen, NULL, 0) + 2;
if (outStr)
{
memset (outStr, 0x00, sizeof (WCHAR)*nOutputStrLen);
MultiByteToWideChar (CP_ACP, 0, pCstring, nInputStrLen, outStr, nInputStrLen);
}
}
}
void write_debug(const char *str)
{
gDXInfo << str; /* Flawfinder: ignore */
}
void write_debug(std::string& str)
{
write_debug(str.c_str());
}
void show_progress(const std::string& message)
{
std::wstring msg = wstring_to_utf16str(utf8str_to_wstring(message));
if (gHwndProgress)
{
SendDlgItemMessage(gHwndProgress, // handle to destination window
IDC_LOG,
WM_SETTEXT, // message to send
FALSE, // undo option
(LPARAM)msg.c_str());
}
}
void update_messages()
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
exit(0);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void sleep_and_pump_messages( U32 seconds )
{
const U32 CYCLES_PER_SECOND = 10;
U32 cycles = seconds * CYCLES_PER_SECOND;
while( cycles-- )
{
update_messages();
ms_sleep(1000 / CYCLES_PER_SECOND);
}
}
// Include product name in the window caption.
void LLCrashLoggerWindows::ProcessCaption(HWND hWnd)
{
TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */
TCHAR header[MAX_STRING];
std::string final;
GetWindowText(hWnd, templateText, sizeof(templateText));
final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());
ConvertLPCSTRToLPWSTR(final.c_str(), header);
SetWindowText(hWnd, header);
}
// Include product name in the diaog item text.
void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem)
{
TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */
TCHAR header[MAX_STRING];
std::string final;
GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText));
final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str());
ConvertLPCSTRToLPWSTR(final.c_str(), header);
SetDlgItemText(hWnd, nIDDlgItem, header);
}
bool handle_button_click(WORD button_id)
{
// Is this something other than Send or Don't Send?
if (button_id != IDOK
&& button_id != IDCANCEL)
{
return false;
}
// See if "do this next time" is checked and save state
S32 crash_behavior = CRASH_BEHAVIOR_ASK;
LRESULT result = SendDlgItemMessage(gHwndReport, IDC_CHECK_AUTO, BM_GETCHECK, 0, 0);
if (result == BST_CHECKED)
{
if (button_id == IDOK)
{
crash_behavior = CRASH_BEHAVIOR_ALWAYS_SEND;
}
else if (button_id == IDCANCEL)
{
crash_behavior = CRASH_BEHAVIOR_NEVER_SEND;
}
((LLCrashLoggerWindows*)LLCrashLogger::instance())->saveCrashBehaviorSetting(crash_behavior);
}
// We're done with this dialog.
gFirstDialog = FALSE;
// Send the crash report if requested
if (button_id == IDOK)
{
gSendLogs = TRUE;
WCHAR wbuffer[20000];
GetDlgItemText(gHwndReport, // handle to dialog box
IDC_EDIT1, // control identifier
wbuffer, // pointer to buffer for text
20000 // maximum size of string
);
std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP));
// Activate and show the window.
ShowWindow(gHwndProgress, SW_SHOW);
// Try doing this second to make the progress window go frontmost.
ShowWindow(gHwndReport, SW_HIDE);
((LLCrashLoggerWindows*)LLCrashLogger::instance())->setUserText(user_text);
((LLCrashLoggerWindows*)LLCrashLogger::instance())->sendCrashLogs();
}
// Quit the app
LLApp::setQuitting();
return true;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_CREATE:
return 0;
case WM_COMMAND:
if( gFirstDialog )
{
WORD button_id = LOWORD(wParam);
bool handled = handle_button_click(button_id);
if (handled)
{
return 0;
}
}
break;
case WM_DESTROY:
// Closing the window cancels
LLApp::setQuitting();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LLCrashLoggerWindows::LLCrashLoggerWindows(void)
{
if (LLCrashLoggerWindows::sInstance==NULL)
{
sInstance = this;
}
}
LLCrashLoggerWindows::~LLCrashLoggerWindows(void)
{
sInstance = NULL;
}
bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to)
{
bool res;
const int timerID=37;
SetTimer(NULL, timerID, to, NULL);
res = GetMessage(msg, NULL, 0, 0);
KillTimer(NULL, timerID);
if (!res)
return false;
if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == 1)
return false; //TIMEOUT! You could call SetLastError() or something...
return true;
}
int LLCrashLoggerWindows::processingLoop() {
const int millisecs=1000;
static int first_connect = 1;
LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
MSG msg;
bool result;
while (1)
{
result = getMessageWithTimeout(&msg, millisecs);
if ( result )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (first_connect )
{
if ( mClientsConnected > 0)
{
first_connect = 0;
}
}
else
{
if (mClientsConnected == 0)
{
break;
}
if (!mKeyMaster.isProcessAlive(mPID, mProcName) )
{
break;
}
}
}
llinfos << "session ending.." << llendl;
llinfos << "clients connected :" << mClientsConnected << llendl;
return 0;
}
void LLCrashLoggerWindows::OnClientConnected(void* context,
const google_breakpad::ClientInfo* client_info)
{
llinfos << "client start. pid = " << client_info->pid() << llendl;
sInstance->mClientsConnected++;
}
void LLCrashLoggerWindows::OnClientExited(void* context,
const google_breakpad::ClientInfo* client_info)
{
llinfos << "client end. pid = " << client_info->pid() << llendl;
sInstance->mClientsConnected--;
}
/*
void LLCrashLoggerWindows::OnClientDumpRequest(void* context,
const google_breakpad::ClientInfo* client_info,
const std::wstring* file_path)
{
ProcessingLock lock;
if (!file_path)
{
llwarns << "dump with no file path" << llendl;
return;
}
if (!client_info)
{
llwarns << "dump with no client info" << llendl;
return;
}
LLCrashLoggerWindows* self = static_cast<LLCrashLoggerWindows*>(context);
if (!self)
{
llwarns << "dump with no context" << llendl;
return;
}
DWORD pid = client_info->pid();
// Send the crash dump using a worker thread. This operation has retry
// logic in case there is no internet connection at the time.
DumpJobInfo* dump_job = new DumpJobInfo(pid, self, map,
dump_location.value());
if (!::QueueUserWorkItem(&CrashService::AsyncSendDump,
dump_job, WT_EXECUTELONGFUNCTION)) {
LOG(ERROR) << "could not queue job";
}
}
*/
bool LLCrashLoggerWindows::initCrashServer()
{
//For Breakpad on Windows we need a full Out of Process service to get good data.
//This routine starts up the service on a named pipe that the viewer will then
//communicate with.
using namespace google_breakpad;
LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
std::string dump_path = options["dumpdir"].asString();
mClientsConnected = 0;
mPID = options["pid"].asInteger();
mProcName = options["procname"].asString();
std::wostringstream ws;
//Generate a quasi-uniq name for the named pipe. For our purposes
//this is unique-enough with least hassle. Worst case for duplicate name
//is a second instance of the viewer will not do crash reporting.
ws << mCrashReportPipeStr << mPID;
std::wstring wpipe_name = ws.str();
std::wstring wdump_path;
wdump_path.assign(dump_path.begin(), dump_path.end());
//Pipe naming conventions: http://msdn.microsoft.com/en-us/library/aa365783%28v=vs.85%29.aspx
mCrashHandler = new CrashGenerationServer( (WCHAR *)wpipe_name.c_str(),
NULL,
&LLCrashLoggerWindows::OnClientConnected, this,
NULL, NULL, // &LLCrashLoggerWindows::OnClientDumpRequest, this,
&LLCrashLoggerWindows::OnClientExited, this,
NULL, NULL,
true, &wdump_path);
if (!mCrashHandler) {
//Failed to start the crash server.
llwarns << "Failed to init crash server." << llendl;
return false;
}
// Start servicing clients.
if (!mCrashHandler->Start()) {
llwarns << "Failed to start crash server." << llendl;
return false;
}
return true;
}
bool LLCrashLoggerWindows::init(void)
{
initCrashServer();
bool ok = LLCrashLogger::init();
if(!ok) return false;
/*
mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) );
gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0;
swprintf(gProductName, L"Second Life");
*/
llinfos << "Loading dialogs" << llendl;
// Initialize global strings
LoadString(mhInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(mhInst, IDC_WIN_CRASH_LOGGER, szWindowClass, MAX_LOADSTRING);
gCursorArrow = LoadCursor(NULL, IDC_ARROW);
gCursorWait = LoadCursor(NULL, IDC_WAIT);
// Register a window class that will be used by our dialogs
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = DLGWINDOWEXTRA; // Required, since this is used for dialogs!
wndclass.hInstance = mhInst;
wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE( IDI_WIN_CRASH_LOGGER ) );
wndclass.hCursor = gCursorArrow;
wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szWindowClass;
RegisterClass( &wndclass );
return true;
}
void LLCrashLoggerWindows::gatherPlatformSpecificFiles()
{
updateApplication("Gathering hardware information. App may appear frozen.");
// DX hardware probe blocks, so we can't cancel during it
//Generate our dx_info.log file
SetCursor(gCursorWait);
// At this point we're responsive enough the user could click the close button
SetCursor(gCursorArrow);
//mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); //Not initialized.
}
bool LLCrashLoggerWindows::mainLoop()
{
llinfos << "CrashSubmitBehavior is " << mCrashBehavior << llendl;
// Note: parent hwnd is 0 (the desktop). No dlg proc. See Petzold (5th ed) HexCalc example, Chapter 11, p529
// win_crash_logger.rc has been edited by hand.
// Dialogs defined with CLASS "WIN_CRASH_LOGGER" (must be same as szWindowClass)
gProductName = mProductName;
gHwndProgress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS), 0, NULL);
ProcessCaption(gHwndProgress);
ShowWindow(gHwndProgress, SW_HIDE );
if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
{
llinfos << "Showing crash report submit progress window." << llendl;
ShowWindow(gHwndProgress, SW_SHOW );
sendCrashLogs();
}
else if (mCrashBehavior == CRASH_BEHAVIOR_ASK)
{
gHwndReport = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PREVREPORTBOX), 0, NULL);
// Ignore result
(void) SendDlgItemMessage(gHwndReport, IDC_CHECK_AUTO, BM_SETCHECK, 0, 0);
// Include the product name in the caption and various dialog items.
ProcessCaption(gHwndReport);
ProcessDlgItemText(gHwndReport, IDC_STATIC_MSG);
// Update the header to include whether or not we crashed on the last run.
std::string headerStr;
TCHAR header[MAX_STRING];
if (mCrashInPreviousExec)
{
headerStr = llformat("%s appears to have crashed or frozen the last time it ran.", mProductName.c_str());
}
else
{
headerStr = llformat("%s appears to have crashed.", mProductName.c_str());
}
ConvertLPCSTRToLPWSTR(headerStr.c_str(), header);
SetDlgItemText(gHwndReport, IDC_STATIC_HEADER, header);
ShowWindow(gHwndReport, SW_SHOW );
MSG msg;
memset(&msg, 0, sizeof(msg));
while (!LLApp::isQuitting() && GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
else
{
llwarns << "Unknown crash behavior " << mCrashBehavior << llendl;
return 1;
}
return 0;
}
void LLCrashLoggerWindows::updateApplication(const std::string& message)
{
LLCrashLogger::updateApplication(message);
if(!message.empty()) show_progress(message);
update_messages();
}
bool LLCrashLoggerWindows::cleanup()
{
if(gSendLogs)
{
if(mSentCrashLogs) show_progress("Done");
else show_progress("Could not connect to servers, logs not sent");
sleep_and_pump_messages(3);
}
PostQuitMessage(0);
commonCleanup();
mKeyMaster.releaseMaster();
return true;
}

View File

@@ -1,86 +0,0 @@
/**
* @file llcrashloggerwindows.h
* @brief Windows crash logger definition
*
* $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$
*/
#ifndef LLCRASHLOGGERWINDOWS_H
#define LLCRASHLOGGERWINDOWS_H
#include "llcrashlogger.h"
#include "windows.h"
#include "llstring.h"
class LLSD;
namespace google_breakpad {
class CrashGenerationServer;
class ClientInfo;
}
class LLCrashLoggerWindows : public LLCrashLogger
{
public:
LLCrashLoggerWindows(void);
~LLCrashLoggerWindows(void);
static LLCrashLoggerWindows* sInstance;
virtual bool init();
virtual bool mainLoop();
virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool cleanup();
virtual void gatherPlatformSpecificFiles();
void setHandle(HINSTANCE hInst) { mhInst = hInst; }
int clients_connected() const {
return mClientsConnected;
}
bool getMessageWithTimeout(MSG *msg, UINT to);
// Starts the processing loop. This function does not return unless the
// user is logging off or the user closes the crash service window. The
// return value is a good number to pass in ExitProcess().
int processingLoop();
private:
void ProcessDlgItemText(HWND hWnd, int nIDDlgItem);
void ProcessCaption(HWND hWnd);
bool initCrashServer();
google_breakpad::CrashGenerationServer* mCrashHandler;
static void OnClientConnected(void* context,
const google_breakpad::ClientInfo* client_info);
/*static void OnClientDumpRequest(
void* context,
const google_breakpad::ClientInfo* client_info,
const std::wstring* file_path);*/
static void OnClientExited(void* context,
const google_breakpad::ClientInfo* client_info);
int mClientsConnected;
int mPID;
std::string mProcName;
HINSTANCE mhInst;
};
#endif

View File

@@ -1,63 +0,0 @@
/**
* @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
//
#define IDC_MYICON 2
#define IDD_REPORT 9
#define IDD_WIN_CRASH_LOGGER_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDS_APP_TITLE 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDS_HELLO 106
#define IDI_WIN_CRASH_LOGGER 107
#define IDI_SMALL 108
#define IDC_WIN_CRASH_LOGGER 109
#define IDR_MAINFRAME 128
#define IDD_PROGRESS 129
#define IDD_PREVREPORTBOX 130
#define IDC_EDIT1 1000
#define IDC_LOG 1004
#define IDC_CHECK_AUTO 1006
#define IDC_STATIC_HEADER 1007
#define IDC_STATIC_WHATINFO 1008
#define IDC_STATIC_MOTIVATION 1009
#define IDC_STATIC_MSG 1010
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1011
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,61 +0,0 @@
/**
* @file win_crash_logger.cpp
* @brief Windows crash logger implementation
*
* $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$
*/
#include "linden_common.h"
#include "stdafx.h"
#include <stdlib.h>
#include "llcrashloggerwindows.h"
#include <iostream>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
llinfos << "Starting crash reporter." << llendl;
LLCrashLoggerWindows app;
app.setHandle(hInstance);
app.parseCommandOptions(__argc, __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())
{
llwarns << "Unable to initialize application." << llendl;
return 1;
}
app.processingLoop();
app.mainLoop();
app.cleanup();
llinfos << "Crash reporter finished normally." << llendl;
return 0;
}

View File

@@ -1,38 +0,0 @@
/**
* @file win_crash_logger.h
* @brief Windows crash logger project includes
*
* $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$
*/
#if !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_)
#define AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "resource.h"
#endif // !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,188 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_WIN_CRASH_LOGGER ICON "ll_icon.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_WIN_CRASH_LOGGER MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_PROGRESS DIALOGEX 100, 100, 234, 33
STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU
CAPTION "%s Crash Logger"
CLASS "WIN_CRASH_LOGGER"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "Static",IDC_LOG,7,7,220,8
END
IDD_REPORT DIALOGEX 100, 100, 297, 125
STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU
CAPTION "%s Crash Logger"
CLASS "WIN_CRASH_LOGGER"
FONT 8, "MS Sans Serif", 0, 0, 0x0
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
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.secondlife.com/support",IDC_STATIC,4,67,231,8
END
IDD_PREVREPORTBOX DIALOGEX 100, 100, 232, 213
STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU
CAPTION "%s Crash Logger"
CLASS "WIN_CRASH_LOGGER"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "Send Report",IDOK,131,193,45,15,WS_GROUP
EDITTEXT IDC_EDIT1,3,100,223,89,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL
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 "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 Linden Lab 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.secondlife.com/support",IDC_STATIC,3,76,206,8
CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,193,89,13
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""resource.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_PROGRESS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 227
TOPMARGIN, 7
BOTTOMMARGIN, 26
END
IDD_REPORT, DIALOG
BEGIN
RIGHTMARGIN, 292
VERTGUIDE, 4
BOTTOMMARGIN, 119
HORZGUIDE, 4
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_APP_TITLE "win_crash_logger"
IDS_HELLO "Hello World!"
IDC_WIN_CRASH_LOGGER "WIN_CRASH_LOGGER"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -1,35 +0,0 @@
# -*- cmake -*-
project(win_updater)
include(00-Common)
include(LLCommon)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
)
set(win_updater_SOURCE_FILES updater.cpp)
set(win_updater_HEADER_FILES CMakeLists.txt)
set_source_files_properties(${win_updater_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND win_updater_SOURCE_FILES ${win_updater_HEADER_FILES})
add_executable(windows-updater WIN32 ${win_updater_SOURCE_FILES})
target_link_libraries(windows-updater
wininet
user32
gdi32
shell32
)
set_target_properties(windows-updater
PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
)

View File

@@ -1,522 +0,0 @@
/**
* @file updater.cpp
* @brief Windows auto-updater
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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$
*/
//
// Usage: updater -url <url>
//
// We use dangerous fopen, strtok, mbstowcs, sprintf
// which generates warnings on VC2005.
// *TODO: Switch to fopen_s, strtok_s, etc.
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <fstream>
#define BUFSIZE 8192
int gTotalBytesRead = 0;
DWORD gTotalBytes = -1;
HWND gWindow = NULL;
WCHAR gProgress[256];
char* gUpdateURL = NULL;
#if _DEBUG
std::ofstream logfile;
#define DEBUG(expr) logfile << expr << std::endl
#else
#define DEBUG(expr) /**/
#endif
char* wchars_to_utf8chars(const WCHAR* in_chars)
{
int tlen = 0;
const WCHAR* twc = in_chars;
while (*twc++ != 0)
{
tlen++;
}
char* outchars = new char[tlen];
char* res = outchars;
for (int i=0; i<tlen; i++)
{
int cur_char = (int)(*in_chars++);
if (cur_char < 0x80)
{
*outchars++ = (char)cur_char;
}
else
{
*outchars++ = '?';
}
}
*outchars = 0;
return res;
}
class Fetcher
{
public:
Fetcher(const std::wstring& uri)
{
// These actions are broken out as separate methods not because it
// makes the code clearer, but to avoid triggering AntiVir and
// McAfee-GW-Edition virus scanners (DEV-31680).
mInet = openInet();
mDownload = openUrl(uri);
}
~Fetcher()
{
DEBUG("Calling InternetCloseHandle");
InternetCloseHandle(mDownload);
InternetCloseHandle(mInet);
}
unsigned long read(char* buffer, size_t bufflen) const;
DWORD getTotalBytes() const
{
DWORD totalBytes;
DWORD sizeof_total_bytes = sizeof(totalBytes);
HttpQueryInfo(mDownload, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
&totalBytes, &sizeof_total_bytes, NULL);
return totalBytes;
}
struct InetError: public std::runtime_error
{
InetError(const std::string& what): std::runtime_error(what) {}
};
private:
// We test results from a number of different MS functions with different
// return types -- but the common characteristic is that 0 (i.e. (! result))
// means an error of some kind.
template <typename RESULT>
static RESULT check(const std::string& desc, RESULT result)
{
if (result)
{
// success, show caller
return result;
}
DWORD err = GetLastError();
std::ostringstream out;
out << desc << " Failed: " << err;
DEBUG(out.str());
throw InetError(out.str());
}
HINTERNET openUrl(const std::wstring& uri) const;
HINTERNET openInet() const;
HINTERNET mInet, mDownload;
};
HINTERNET Fetcher::openInet() const
{
DEBUG("Calling InternetOpen");
// Init wininet subsystem
return check("InternetOpen",
InternetOpen(L"LindenUpdater", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0));
}
HINTERNET Fetcher::openUrl(const std::wstring& uri) const
{
DEBUG("Calling InternetOpenUrl: " << wchars_to_utf8chars(uri.c_str()));
return check("InternetOpenUrl",
InternetOpenUrl(mInet, uri.c_str(), NULL, 0, INTERNET_FLAG_NEED_FILE, NULL));
}
unsigned long Fetcher::read(char* buffer, size_t bufflen) const
{
unsigned long bytes_read = 0;
DEBUG("Calling InternetReadFile");
check("InternetReadFile",
InternetReadFile(mDownload, buffer, bufflen, &bytes_read));
return bytes_read;
}
int WINAPI get_url_into_file(const std::wstring& uri, const std::string& path, int *cancelled)
{
int success = FALSE;
*cancelled = FALSE;
DEBUG("Opening '" << path << "'");
FILE* fp = fopen(path.c_str(), "wb"); /* Flawfinder: ignore */
if (!fp)
{
DEBUG("Failed to open '" << path << "'");
return success;
}
// Note, ctor can throw, since it uses check() function.
Fetcher fetcher(uri);
gTotalBytes = fetcher.getTotalBytes();
/*==========================================================================*|
// nobody uses total_bytes?!? What's this doing here?
DWORD total_bytes = 0;
success = check("InternetQueryDataAvailable",
InternetQueryDataAvailable(hdownload, &total_bytes, 0, 0));
|*==========================================================================*/
success = FALSE;
while(!success && !(*cancelled))
{
char data[BUFSIZE]; /* Flawfinder: ignore */
unsigned long bytes_read = fetcher.read(data, sizeof(data));
if (!bytes_read)
{
DEBUG("InternetReadFile Read " << bytes_read << " bytes.");
}
DEBUG("Reading Data, bytes_read = " << bytes_read);
if (bytes_read == 0)
{
// If InternetFileRead returns TRUE AND bytes_read == 0
// we've successfully downloaded the entire file
wsprintf(gProgress, L"Download complete.");
success = TRUE;
}
else
{
// write what we've got, then continue
fwrite(data, sizeof(char), bytes_read, fp);
gTotalBytesRead += int(bytes_read);
if (gTotalBytes != -1)
wsprintf(gProgress, L"Downloaded: %d%%", 100 * gTotalBytesRead / gTotalBytes);
else
wsprintf(gProgress, L"Downloaded: %dK", gTotalBytesRead / 1024);
}
DEBUG("Calling InvalidateRect");
// Mark the window as needing redraw (of the whole thing)
InvalidateRect(gWindow, NULL, TRUE);
// Do the redraw
DEBUG("Calling UpdateWindow");
UpdateWindow(gWindow);
DEBUG("Calling PeekMessage");
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
{
// bail out, user cancelled
*cancelled = TRUE;
}
}
}
fclose(fp);
return success;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
HDC hdc; // Drawing context
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
RECT rect;
GetClientRect(hwnd, &rect);
DrawText(hdc, gProgress, -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
}
case WM_CLOSE:
case WM_DESTROY:
// Get out of full screen
// full_screen_mode(false);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
#define win_class_name L"FullScreen"
int parse_args(int argc, char **argv)
{
int j;
for (j = 1; j < argc; j++)
{
if ((!strcmp(argv[j], "-url")) && (++j < argc))
{
gUpdateURL = argv[j];
}
}
// If nothing was set, let the caller know.
if (!gUpdateURL)
{
return 1;
}
return 0;
}
int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// Parse the command line.
LPSTR cmd_line_including_exe_name = GetCommandLineA();
const int MAX_ARGS = 100;
int argc = 0;
char* argv[MAX_ARGS]; /* Flawfinder: ignore */
#if _DEBUG
logfile.open("updater.log", std::ios_base::out);
DEBUG("Parsing command arguments");
#endif
char *token = NULL;
if( cmd_line_including_exe_name[0] == '\"' )
{
// Exe name is enclosed in quotes
token = strtok( cmd_line_including_exe_name, "\"" );
argv[argc++] = token;
token = strtok( NULL, " \t," );
}
else
{
// Exe name is not enclosed in quotes
token = strtok( cmd_line_including_exe_name, " \t," );
}
while( (token != NULL) && (argc < MAX_ARGS) )
{
argv[argc++] = token;
/* Get next token: */
if (*(token + strlen(token) + 1) == '\"') /* Flawfinder: ignore */
{
token = strtok( NULL, "\"");
}
else
{
token = strtok( NULL, " \t," );
}
}
gUpdateURL = NULL;
/////////////////////////////////////////
//
// Process command line arguments
//
DEBUG("Processing command arguments");
//
// Parse the command line arguments
//
int parse_args_result = parse_args(argc, argv);
WNDCLASSEX wndclassex = { 0 };
//DEVMODE dev_mode = { 0 };
const int WINDOW_WIDTH = 250;
const int WINDOW_HEIGHT = 100;
wsprintf(gProgress, L"Connecting...");
/* Init the WNDCLASSEX */
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.hInstance = hInstance;
wndclassex.lpfnWndProc = WinProc;
wndclassex.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclassex.lpszClassName = win_class_name;
RegisterClassEx(&wndclassex);
// Get the size of the screen
//EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode);
gWindow = CreateWindowEx(NULL, win_class_name,
L"Second Life Updater",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL, NULL, hInstance, NULL);
ShowWindow(gWindow, nShowCmd);
UpdateWindow(gWindow);
if (parse_args_result)
{
MessageBox(gWindow,
L"Usage: updater -url <url> [-name <window_title>] [-program <program_name>] [-silent]",
L"Usage", MB_OK);
return parse_args_result;
}
// Did we get a userserver to work with?
if (!gUpdateURL)
{
MessageBox(gWindow, L"Please specify the download url from the command line",
L"Error", MB_OK);
return 1;
}
// Can't feed GetTempPath into GetTempFile directly
char temp_path[MAX_PATH]; /* Flawfinder: ignore */
if (0 == GetTempPathA(sizeof(temp_path), temp_path))
{
MessageBox(gWindow, L"Problem with GetTempPath()",
L"Error", MB_OK);
return 1;
}
std::string update_exec_path(temp_path);
update_exec_path.append("Second_Life_Updater.exe");
WCHAR update_uri[4096];
mbstowcs(update_uri, gUpdateURL, sizeof(update_uri));
int success = 0;
int cancelled = 0;
// Actually do the download
try
{
DEBUG("Calling get_url_into_file");
success = get_url_into_file(update_uri, update_exec_path, &cancelled);
}
catch (const Fetcher::InetError& e)
{
(void)e;
success = FALSE;
DEBUG("Caught: " << e.what());
}
// WinInet can't tell us if we got a 404 or not. Therefor, we check
// for the size of the downloaded file, and assume that our installer
// will always be greater than 1MB.
if (gTotalBytesRead < (1024 * 1024) && ! cancelled)
{
MessageBox(gWindow,
L"The Second Life auto-update has failed.\n"
L"The problem may be caused by other software installed \n"
L"on your computer, such as a firewall.\n"
L"Please visit http://secondlife.com/download/ \n"
L"to download the latest version of Second Life.\n",
NULL, MB_OK);
return 1;
}
if (cancelled)
{
// silently exit
return 0;
}
if (!success)
{
MessageBox(gWindow,
L"Second Life download failed.\n"
L"Please try again later.",
NULL, MB_OK);
return 1;
}
// TODO: Make updates silent (with /S to NSIS)
//char params[256]; /* Flawfinder: ignore */
//sprintf(params, "/S"); /* Flawfinder: ignore */
//MessageBox(gWindow,
// L"Updating Second Life.\n\nSecond Life will automatically start once the update is complete. This may take a minute...",
// L"Download Complete",
// MB_OK);
/*==========================================================================*|
// DEV-31680: ShellExecuteA() causes McAfee-GW-Edition and AntiVir
// scanners to flag this executable as a probable virus vector.
// Less than or equal to 32 means failure
if (32 >= (int) ShellExecuteA(gWindow, "open", update_exec_path.c_str(), NULL,
"C:\\", SW_SHOWDEFAULT))
|*==========================================================================*/
// from http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (! CreateProcessA(update_exec_path.c_str(), // executable file
NULL, // command line
NULL, // process cannot be inherited
NULL, // thread cannot be inherited
FALSE, // do not inherit existing handles
0, // process creation flags
NULL, // inherit parent's environment
NULL, // inherit parent's current dir
&si, // STARTUPINFO
&pi)) // PROCESS_INFORMATION
{
MessageBox(gWindow, L"Update failed. Please try again later.", NULL, MB_OK);
return 1;
}
// Give installer some time to open a window
Sleep(1000);
return 0;
}