diff options
| -rw-r--r-- | autobuild.xml | 14 | ||||
| -rwxr-xr-x | build.sh | 34 | ||||
| -rw-r--r-- | indra/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 67 | ||||
| -rw-r--r-- | indra/newview/VIEWER_VERSION.txt | 2 | ||||
| -rwxr-xr-x | indra/newview/installers/darwin/apple-notarize.sh | 54 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llappviewermacosx.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/llappviewerwin32.h | 1 | ||||
| -rw-r--r-- | indra/newview/llsecapi.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llsecapi.h | 2 | ||||
| -rw-r--r-- | indra/newview/slplugin.entitlements | 8 | ||||
| -rwxr-xr-x | indra/newview/viewer_manifest.py | 13 | ||||
| -rw-r--r-- | indra/win_crash_logger/llcrashloggerwindows.cpp | 536 | 
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> @@ -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; -} -  | 
