summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autobuild.xml14
-rwxr-xr-xbuild.sh34
-rw-r--r--indra/CMakeLists.txt11
-rw-r--r--indra/newview/CMakeLists.txt67
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/installers/darwin/apple-notarize.sh54
-rw-r--r--indra/newview/llappviewer.cpp4
-rw-r--r--indra/newview/llappviewermacosx.cpp31
-rw-r--r--indra/newview/llappviewerwin32.h1
-rw-r--r--indra/newview/llsecapi.cpp6
-rw-r--r--indra/newview/llsecapi.h2
-rw-r--r--indra/newview/slplugin.entitlements8
-rwxr-xr-xindra/newview/viewer_manifest.py13
-rw-r--r--indra/win_crash_logger/llcrashloggerwindows.cpp536
14 files changed, 118 insertions, 665 deletions
diff --git a/autobuild.xml b/autobuild.xml
index b1fa096138..d62a00fab9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -580,9 +580,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>49fff41e17e06cdf9eb0c737d20df52f</string>
+ <string>45dedb5b09995cd794304150e94fcf21</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87950/806969/dullahan-1.12.2.202109170444_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-563968.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -592,9 +592,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>f51f324d50a2461cda273e84fa65e0ad</string>
+ <string>d0fd9d7086699da4bb5ccc935622a717</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88276/809277/dullahan-1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-563968.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -604,16 +604,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d3df46f6592715c75df2bf520c1ad68b</string>
+ <string>7e8c3ccd420ff5aef24ff72d609ba394</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88275/809281/dullahan-1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-563968.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
+ <string>1.12.2.202109230751_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>elfio</key>
<map>
diff --git a/build.sh b/build.sh
index 96bcff0e8e..50eb2916df 100755
--- a/build.sh
+++ b/build.sh
@@ -16,6 +16,29 @@
# * The special style in which python is invoked is intentional to permit
# use of a native python install on windows - which requires paths in DOS form
+retry_cmd()
+{
+ max_attempts="$1"; shift
+ initial_wait="$1"; shift
+ attempt_num=1
+ echo "trying" "$@"
+ until "$@"
+ do
+ if ((attempt_num==max_attempts))
+ then
+ echo "Last attempt $attempt_num failed"
+ return 1
+ else
+ wait_time=$(($attempt_num*$initial_wait))
+ echo "Attempt $attempt_num failed. Trying again in $wait_time seconds..."
+ sleep $wait_time
+ attempt_num=$(($attempt_num+1))
+ fi
+ done
+ echo "succeeded"
+ return 0
+}
+
build_dir_Darwin()
{
echo build-darwin-x86_64
@@ -447,7 +470,7 @@ then
succeeded=$build_coverity
else
# Upload base package.
- python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
+ retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
|| fatal "Upload of installer failed"
wait_for_codeticket
@@ -457,7 +480,7 @@ then
package=$(installer_$arch "$package_id")
if [ x"$package" != x ]
then
- python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
+ retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
|| fatal "Upload of installer $package_id failed"
wait_for_codeticket
else
@@ -471,7 +494,7 @@ then
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
# Upload crash reporter file
- python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
+ retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|| fatal "Upload of symbolfile failed"
wait_for_codeticket
fi
@@ -481,10 +504,7 @@ then
if [ -r "$build_dir/llphysicsextensions_package" ]
then
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
- # This next upload is a frequent failure; see if giving the last one some time helps
- # JJ is making changes to Codeticket that we hope will eliminate this failure soon
- sleep 300
- python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
+ retry_cmd 4 30 python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
|| fatal "Upload of physics extensions package failed"
fi
fi
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index db88e44127..bc2ee2e6cd 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -95,17 +95,6 @@ if (USE_BUGSPLAT)
endif (BUGSPLAT_DB)
else (USE_BUGSPLAT)
message(STATUS "Not building with BugSplat")
- 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_dependencies(viewer mac-crash-logger)
- elseif (WINDOWS)
- add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
- # add_dependencies(viewer windows-setup windows-crash-logger)
- add_dependencies(viewer windows-crash-logger)
- endif (LINUX)
endif (USE_BUGSPLAT)
add_subdirectory(${VIEWER_PREFIX}newview)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 87caca56af..e77c062989 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1915,10 +1915,6 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
- if (NOT USE_BUGSPLAT)
- add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger)
- endif (NOT USE_BUGSPLAT)
-
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
if (NOT UNATTENDED)
@@ -2226,10 +2222,6 @@ if (DARWIN)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef)
- if (NOT USE_BUGSPLAT)
- add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
- endif (NOT USE_BUGSPLAT)
-
if (ENABLE_SIGNING)
set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
else (ENABLE_SIGNING)
@@ -2271,62 +2263,7 @@ endif (INSTALL)
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
- if (NOT USE_BUGSPLAT)
- # Breakpad symbol-file generation
- set(SYMBOL_SEARCH_DIRS "")
- if (WINDOWS)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
- # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
- # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
- set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
- set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
- set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
- endif (WINDOWS)
- if (DARWIN)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
- # *TODO: Generate these search dirs in the cmake files related to each binary.
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
- set(VIEWER_EXE_GLOBS "'${product}' SLPlugin")
- set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
- set(VIEWER_LIB_GLOB "*.dylib")
- endif (DARWIN)
- if (LINUX)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
- set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
- set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin")
- set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
- set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
- endif (LINUX)
-
- if(CMAKE_CFG_INTDIR STREQUAL ".")
- set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
- else(CMAKE_CFG_INTDIR STREQUAL ".")
- # set LLBUILD_CONFIG to be a shell variable evaluated at build time
- # reflecting the configuration we are currently building.
- set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
- endif(CMAKE_CFG_INTDIR STREQUAL ".")
- add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
- COMMAND "${PYTHON_EXECUTABLE}"
- ARGS
- "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
- "${LLBUILD_CONFIG}"
- "${SYMBOL_SEARCH_DIRS}"
- "${VIEWER_EXE_GLOBS}"
- "${VIEWER_LIB_GLOB}"
- "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
- "${VIEWER_SYMBOL_FILE}"
- DEPENDS generate_breakpad_symbols.py
- VERBATIM)
-
- add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
- add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
- if (WINDOWS OR LINUX)
- add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
- endif (WINDOWS OR LINUX)
-
- else (NOT USE_BUGSPLAT)
+ if (USE_BUGSPLAT)
# BugSplat symbol-file generation
if (WINDOWS)
# Just pack up a tarball containing only the .pdb file for the
@@ -2410,7 +2347,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
if (LINUX)
# TBD
endif (LINUX)
- endif (NOT USE_BUGSPLAT)
+ endif (USE_BUGSPLAT)
# for both Bugsplat and Breakpad
add_dependencies(llpackage generate_symbols)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 4c8366c864..f186cd8874 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.23
+6.4.24
diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh
new file mode 100755
index 0000000000..466898ecda
--- /dev/null
+++ b/indra/newview/installers/darwin/apple-notarize.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+if [[ $SKIP_NOTARIZATION == "true" ]]; then
+ echo "Skipping notarization"
+ exit 0
+fi
+
+CONFIG_FILE="$build_secrets_checkout/code-signing-osx/notarize_creds.sh"
+if [ -f "$CONFIG_FILE" ]; then
+ source $CONFIG_FILE
+ app_file="$1"
+ zip_file=${app_file/app/zip}
+ ditto -c -k --keepParent "$app_file" "$zip_file"
+ if [ -f "$zip_file" ]; then
+ res=$(xcrun altool --notarize-app --primary-bundle-id "com.secondlife.viewer" \
+ --username $USERNAME \
+ --password $PASSWORD \
+ --asc-provider $ASC_PROVIDER \
+ --file "$zip_file" 2>&1)
+ requestUUID=$(echo $res | awk '/RequestUUID/ { print $NF; }')
+
+ echo "Apple Notarization RequestUUID: $requestUUID"
+
+ if [[ -n $requestUUID ]]; then
+ status="in progress"
+ while [[ "$status" == "in progress" ]]; do
+ sleep 30
+ status=$(xcrun altool --notarization-info "$requestUUID" \
+ --username $USERNAME \
+ --password $PASSWORD 2>&1 \
+ | awk -F ': ' '/Status:/ { print $2; }' )
+ echo "$status"
+ done
+ # log results
+ xcrun altool --notarization-info "$requestUUID" \
+ --username $USERNAME \
+ --password $PASSWORD
+
+ #remove temporary file
+ rm "$zip_file"
+
+ if [["$status" == "success"]]; then
+ xcrun stapler staple "$app_file"
+ elif [["$status" == "invalid"]]; then
+ echo "Notarization error: failed to process the app file"
+ exit 1
+ fi
+ else
+ echo "Notarization error: couldn't get request UUID"
+ echo $res
+ exit 1
+ fi
+ fi
+fi
+
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 585739eca4..ebe1e3f826 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2008,7 +2008,9 @@ bool LLAppViewer::cleanup()
if (LLConversationLog::instanceExists())
{
LLConversationLog::instance().cache();
- }
+ }
+
+ clearSecHandler();
if (mPurgeCacheOnExit)
{
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 42946e4415..aa932f9c89 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -222,14 +222,7 @@ LLAppViewerMacOSX::~LLAppViewerMacOSX()
bool LLAppViewerMacOSX::init()
{
- bool success = LLAppViewer::init();
-
- if (success)
- {
- LLAppViewer* pApp = LLAppViewer::instance();
- pApp->initCrashReporting();
- }
- return success;
+ return LLAppViewer::init();
}
// MacOSX may add and addition command line arguement for the process serial number.
@@ -347,28 +340,6 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
return reset_count == 0;
}
-void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)
-{
-#if defined LL_BUGSPLAT
- LL_DEBUGS("InitOSX", "Bugsplat") << "using BugSplat crash logger" << LL_ENDL;
-#elif LL_SEND_CRASH_REPORTS
- LL_DEBUGS("InitOSX") << "Initializing legacy crash logger" << LL_ENDL;
- std::string command_str = "mac-crash-logger.app";
-
- std::stringstream pid_str;
- pid_str << LLApp::getPid();
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
- std::string appname = gDirUtilp->getExecutableFilename();
- std::string str[] = { "-pid", pid_str.str(), "-dumpdir", logdir, "-procname", appname.c_str() };
- std::vector< std::string > args( str, str + ( sizeof ( str ) / sizeof ( std::string ) ) );
- LL_WARNS() << "about to launch mac-crash-logger" << pid_str.str()
- << " " << logdir << " " << appname << LL_ENDL;
- launchApplication(&command_str, &args);
-#else
- LL_DEBUGS("InitOSX") << "No crash logger enabled" << LL_ENDL;
-#endif // ! LL_BUGSPLAT
-}
-
std::string LLAppViewerMacOSX::generateSerialNumber()
{
char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index 83ae875a15..ab52bf15f9 100644
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -53,7 +53,6 @@ protected:
bool beingDebugged() override;
bool restoreErrorTrap() override;
- void initCrashReporting(bool reportFreeze) override;
bool sendURLToOtherInstance(const std::string& url) override;
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index b9259cb18d..aba8ca5a4a 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -75,6 +75,12 @@ void initializeSecHandler()
}
}
+
+void clearSecHandler()
+{
+ gSecAPIHandler = NULL;
+ gHandlerMap.clear();
+}
// start using a given security api handler. If the string is empty
// the default is used
LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 14059f828a..47091aa3b2 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -533,6 +533,8 @@ public:
};
void initializeSecHandler();
+
+void clearSecHandler();
// retrieve a security api depending on the api type
LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type);
diff --git a/indra/newview/slplugin.entitlements b/indra/newview/slplugin.entitlements
new file mode 100644
index 0000000000..a1c430a57a
--- /dev/null
+++ b/indra/newview/slplugin.entitlements
@@ -0,0 +1,8 @@
+<?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>com.apple.security.cs.allow-unsigned-executable-memory</key>
+ <true/>
+</dict>
+</plist>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 41da8fa328..8b4184d13c 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1296,12 +1296,13 @@ class DarwinManifest(ViewerManifest):
sign_retry_wait=15
while (not signed) and (sign_attempts > 0):
try:
- sign_attempts-=1;
- self.run_command(
- # Note: See blurb above about names of keychains
- ['codesign', '--verbose', '--deep', '--force',
- '--keychain', viewer_keychain, '--sign', identity,
- app_in_dmg])
+ sign_attempts-=1
+ # Note: See blurb above about names of keychains
+ self.run_command(['codesign', '--force', '--timestamp','--keychain', viewer_keychain, '--sign', identity, libvlc_path])
+ self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, cef_path])
+ self.run_command(['codesign', '--force', '--timestamp', '--keychain', viewer_keychain, '--sign', identity, greenlet_path])
+ self.run_command(['codesign', '--verbose', '--deep', '--force', '--entitlements', self.src_path_of("slplugin.entitlements"), '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, slplugin_path])
+ self.run_command(['codesign', '--verbose', '--deep', '--force', '--options', 'runtime', '--keychain', viewer_keychain, '--sign', identity, app_in_dmg])
signed=True # if no exception was raised, the codesign worked
except ManifestError as err:
if sign_attempts:
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
deleted file mode 100644
index 0cbe0b0d17..0000000000
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ /dev/null
@@ -1,536 +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 "stringize.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;
- }
-
- // 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;
- UINT_PTR timerID = SetTimer(NULL, NULL, 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;
- int retries = 0;
- const int max_retries = 60;
-
- LL_DEBUGS("CRASHREPORT") << "Entering processing loop for OOP server" << LL_ENDL;
-
- LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
-
- MSG msg;
-
- bool result;
-
- while (1)
- {
- result = getMessageWithTimeout(&msg, millisecs);
- if ( result )
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- if ( retries < max_retries ) //Wait up to 1 minute for the viewer to say hello.
- {
- if (mClientsConnected == 0)
- {
- LL_DEBUGS("CRASHREPORT") << "Waiting for client to connect." << LL_ENDL;
- ++retries;
- }
- else
- {
- LL_INFOS("CRASHREPORT") << "Client has connected!" << LL_ENDL;
- retries = max_retries;
- }
- }
- else
- {
- if (mClientsConnected == 0)
- {
- break;
- }
- if (!mKeyMaster.isProcessAlive(mPID, mProcName) )
- {
- break;
- }
- }
- }
-
- LL_INFOS() << "session ending.." << LL_ENDL;
-
- std::string per_run_dir = options["dumpdir"].asString();
- std::string per_run_file = per_run_dir + "\\SecondLife.log";
- std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
-
- if (gDirUtilp->fileExists(per_run_dir))
- {
- LL_INFOS ("CRASHREPORT") << "Copying " << log_file << " to " << per_run_file << LL_ENDL;
- LLFile::copy(log_file, per_run_file);
- }
- return 0;
-}
-
-
-void LLCrashLoggerWindows::OnClientConnected(void* context,
- const google_breakpad::ClientInfo* client_info)
-{
- sInstance->mClientsConnected++;
- LL_INFOS("CRASHREPORT") << "Client connected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
-}
-
-void LLCrashLoggerWindows::OnClientExited(void* context,
- const google_breakpad::ClientInfo* client_info)
-{
- sInstance->mClientsConnected--;
- LL_INFOS("CRASHREPORT") << "Client disconnected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
-}
-
-
-void LLCrashLoggerWindows::OnClientDumpRequest(void* context,
- const google_breakpad::ClientInfo* client_info,
- const std::wstring* file_path)
-{
- if (!file_path)
- {
- LL_WARNS() << "dump with no file path" << LL_ENDL;
- return;
- }
- if (!client_info)
- {
- LL_WARNS() << "dump with no client info" << LL_ENDL;
- return;
- }
-
- LLCrashLoggerWindows* self = static_cast<LLCrashLoggerWindows*>(context);
- if (!self)
- {
- LL_WARNS() << "dump with no context" << LL_ENDL;
- return;
- }
-
- //DWORD pid = client_info->pid();
-}
-
-
-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();
-
- //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.
- std::wstring wpipe_name;
- wpipe_name = mCrashReportPipeStr + std::wstring(wstringize(mPID));
-
- std::wstring wdump_path(utf8str_to_utf16str(dump_path));
-
- //Pipe naming conventions: http://msdn.microsoft.com/en-us/library/aa365783%28v=vs.85%29.aspx
- mCrashHandler = new CrashGenerationServer( wpipe_name,
- 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.
- LL_WARNS() << "Failed to init crash server." << LL_ENDL;
- return false;
- }
-
- // Start servicing clients.
- if (!mCrashHandler->Start()) {
- LL_WARNS() << "Failed to start crash server." << LL_ENDL;
- return false;
- }
-
- LL_INFOS("CRASHREPORT") << "Initialized OOP server with pipe named " << stringize(wpipe_name) << LL_ENDL;
- return true;
-}
-
-bool LLCrashLoggerWindows::init(void)
-{
- bool ok = LLCrashLogger::init();
- if(!ok) return false;
-
- initCrashServer();
-
- /*
- mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) );
- gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0;
- swprintf(gProductName, L"Second Life");
- */
-
- LL_INFOS() << "Loading dialogs" << LL_ENDL;
-
- // 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::frame()
-{
- LL_INFOS() << "CrashSubmitBehavior is " << mCrashBehavior << LL_ENDL;
-
- // 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)
- {
- LL_INFOS() << "Showing crash report submit progress window." << LL_ENDL;
- //ShowWindow(gHwndProgress, SW_SHOW ); Maint-5707
- 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::isExiting() && GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return true; // msg.wParam;
- }
- else
- {
- LL_WARNS() << "Unknown crash behavior " << mCrashBehavior << LL_ENDL;
- return true; // 1;
- }
- return true; // 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;
-}
-