Merge viewer-bugsplat

master
Ansariel 2018-08-31 09:17:34 +02:00
commit 6bd724e65a
14 changed files with 481 additions and 253 deletions

View File

@ -448,9 +448,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f01caa9aeb4c19f679e60609e6095335</string>
<string>7a7bd828233e8a2b0e9c022f6219e6e7</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23285/178722/bugsplat-1.0.5.518876-darwin64-518876.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -460,9 +460,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>17f0e6d2fce03ae48ac02ccaebe48f61</string>
<string>a3938332a11215e6909d67d1b9be5259</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23286/178729/bugsplat-3.6.0.4.518876-windows-518876.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -472,16 +472,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e963a42106ed0fc8b87974cfce040714</string>
<string>453d624d87a80779f59cfb1880613d90</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23284/178715/bugsplat-3.6.0.4.518876-windows64-518876.tar.bz2</string>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.0.5.518876</string>
<string>1.0.6.519145</string>
</map>
<key>chardet</key>
<map>

View File

@ -103,6 +103,23 @@ pre_build()
"-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
fi
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
case "$arch" in
CYGWIN)
symplat="windows"
;;
Darwin)
symplat="darwin"
;;
Linux)
symplat="linux"
;;
esac
# This name is consumed by indra/newview/CMakeLists.txt
VIEWER_SYMBOL_FILE="$build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2"
fi
# don't spew credentials into build log
bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
set +x
@ -122,6 +139,8 @@ pre_build()
-DPACKAGE:BOOL=ON \
-DHAVOK:BOOL="$HAVOK" \
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
-DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" \
-DBUGSPLAT_DB:STRING="${BUGSPLAT_DB:-}" \
-DVIEWER_CHANNEL:STRING="${viewer_channel}" \
-DGRID:STRING="\"$viewer_grid\"" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
@ -244,7 +263,6 @@ initialize_version # provided by buildscripts build.sh; sets version id
# Now run the build
succeeded=true
build_processes=
last_built_variant=
for variant in $variants
do
@ -252,7 +270,6 @@ do
last_built_variant="$variant"
build_dir=`build_dir_$arch $variant`
build_dir_stubs="$build_dir/win_setup/$variant"
begin_section "Initialize $variant Build Directory"
rm -rf "$build_dir"
@ -423,24 +440,10 @@ then
if [ "$last_built_variant" = "Release" ]
then
# nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
# Likewise, BUGSPLAT_DB suppresses generating the symbol file.
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" \
-a -z "${BUGSPLAT_DB:-}" ]
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
# Upload crash reporter file
# These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt
case "$arch" in
CYGWIN)
symbolfile="$build_dir/newview/Release/secondlife-symbols-windows-${AUTOBUILD_ADDRSIZE}.tar.bz2"
;;
Darwin)
symbolfile="$build_dir/newview/Release/secondlife-symbols-darwin-${AUTOBUILD_ADDRSIZE}.tar.bz2"
;;
Linux)
symbolfile="$build_dir/newview/Release/secondlife-symbols-linux-${AUTOBUILD_ADDRSIZE}.tar.bz2"
;;
esac
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$symbolfile" \
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|| fatal "Upload of symbolfile failed"
fi

View File

@ -51,7 +51,7 @@ if(WINDOWS)
# Filenames are different for 32/64 bit BugSplat file and we don't
# have any control over them so need to branch.
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
if(ADDRESS_SIZE EQUAL 32)
set(release_files ${release_files} BugSplat.dll)
set(release_files ${release_files} BugSplatRc.dll)
@ -61,7 +61,7 @@ if(WINDOWS)
set(release_files ${release_files} BugSplatRc64.dll)
set(release_files ${release_files} BsSndRpt64.exe)
endif(ADDRESS_SIZE EQUAL 32)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
set(release_files ${release_files} growl++.dll growl.dll )
if (FMODSTUDIO)

View File

@ -33,6 +33,8 @@ set(INTEGRATION_TESTS_PREFIX)
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
if(LIBS_CLOSED_DIR)
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)

View File

@ -1,7 +1,6 @@
# BugSplat is engaged by setting environment variable BUGSPLAT_DB to the
# target BugSplat database name prior to running CMake (and during autobuild
# build).
if (DEFINED ENV{BUGSPLAT_DB})
# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
# name.
if (BUGSPLAT_DB)
if (USESYSTEMLIBS)
message(STATUS "Looking for system BugSplat")
set(BUGSPLAT_FIND_QUIETLY ON)
@ -23,4 +22,4 @@ if (DEFINED ENV{BUGSPLAT_DB})
endif (WINDOWS)
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
endif (USESYSTEMLIBS)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)

View File

@ -33,13 +33,14 @@ import filecmp
import fnmatch
import getopt
import glob
import itertools
import operator
import os
import re
import shutil
import subprocess
import sys
import tarfile
import errno
import subprocess
class ManifestError(RuntimeError):
"""Use an exception more specific than generic Python RuntimeError"""
@ -90,7 +91,7 @@ DEFAULT_SRCTREE = os.path.dirname(sys.argv[0])
CHANNEL_VENDOR_BASE = 'Firestorm'
RELEASE_CHANNEL = CHANNEL_VENDOR_BASE + ' Development'
ARGUMENTS=[
BASE_ARGUMENTS=[
dict(name='actions',
description="""This argument specifies the actions that are to be taken when the
script is run. The meaningful actions are currently:
@ -108,8 +109,19 @@ ARGUMENTS=[
Example use: %(name)s --arch=i686
On Linux this would try to use Linux_i686Manifest.""",
default=""),
dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE),
dict(name='buildtype', description='Build type (i.e. Debug, Release, RelWithDebInfo).', default=None),
dict(name='bundleid',
description="""The Mac OS X Bundle identifier.""",
default="com.secondlife.indra.viewer"),
dict(name='channel',
description="""The channel to use for updates, packaging, settings name, etc.""",
default='CHANNEL UNSET'),
dict(name='channel_suffix',
description="""Addition to the channel for packaging and channel value,
but not application name (used internally)""",
default=None),
dict(name='configuration',
description="""The build configuration used.""",
default="Release"),
@ -117,12 +129,6 @@ ARGUMENTS=[
dict(name='grid',
description="""Which grid the client will try to connect to.""",
default=None),
dict(name='channel',
description="""The channel to use for updates, packaging, settings name, etc.""",
default='CHANNEL UNSET'),
dict(name='channel_suffix',
description="""Addition to the channel for packaging and channel value, but not application name (used internally)""",
default=None),
dict(name='installer_name',
description=""" The name of the file that the installer should be
packaged up into. Only used on Linux at the moment.""",
@ -134,10 +140,14 @@ ARGUMENTS=[
description="""The current platform, to be used for looking up which
manifest class to run.""",
default=get_default_platform),
dict(name='signature',
description="""This specifies an identity to sign the viewer with, if any.
If no value is supplied, the default signature will be used, if any. Currently
only used on Mac OS X.""",
default=None),
dict(name='source',
description='Source directory.',
default=DEFAULT_SRCTREE),
dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
dict(name='touch',
description="""File to touch when action is finished. Touch file will
contain the name of the final package in a form suitable
@ -145,24 +155,17 @@ ARGUMENTS=[
default=None),
dict(name='versionfile',
description="""The name of a file containing the full version number."""),
dict(name='bundleid',
description="""The Mac OS X Bundle identifier.""",
default="com.secondlife.indra.viewer"),
dict(name='signature',
description="""This specifies an identity to sign the viewer with, if any.
If no value is supplied, the default signature will be used, if any. Currently
only used on Mac OS X.""",
default=None),
dict(name='viewer_flavor', description='Type of viewer build. Can be oss or hvk.', default="oss"),
dict(name='viewer_flavor',
description='Type of viewer build. Can be oss or hvk.', default="oss"),
]
def usage(srctree=""):
def usage(arguments, srctree=""):
nd = {'name':sys.argv[0]}
print """Usage:
%(name)s [options] [destdir]
Options:
""" % nd
for arg in ARGUMENTS:
for arg in arguments:
default = arg['default']
if hasattr(default, '__call__'):
default = "(computed value) \"" + str(default(srctree)) + '"'
@ -173,11 +176,15 @@ def usage(srctree=""):
default,
arg['description'] % nd)
def main():
## import itertools
def main(extra=[]):
## print ' '.join((("'%s'" % item) if ' ' in item else item)
## for item in itertools.chain([sys.executable], sys.argv))
option_names = [arg['name'] + '=' for arg in ARGUMENTS]
# Supplement our default command-line switches with any desired by
# application-specific caller.
arguments = list(itertools.chain(BASE_ARGUMENTS, extra))
# Alphabetize them by option name in case we display usage.
arguments.sort(key=operator.itemgetter('name'))
option_names = [arg['name'] + '=' for arg in arguments]
option_names.append('help')
options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
@ -200,11 +207,11 @@ def main():
# early out for help
if 'help' in args:
# *TODO: it is a huge hack to pass around the srctree like this
usage(args['source'])
usage(arguments, srctree=args['source'])
return
# defaults
for arg in ARGUMENTS:
for arg in arguments:
if arg['name'] not in args:
default = arg['default']
if hasattr(default, '__call__'):

View File

@ -281,10 +281,10 @@ list(APPEND llcommon_HEADER_FILES "tea.h" )
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
set_source_files_properties(llapp.cpp
PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})

View File

@ -8,9 +8,9 @@ include(00-Common)
include(Linking)
include(Boost)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
include(bugsplat)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@ -116,11 +116,11 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
include_directories(
${BUGSPLAT_INCLUDE_DIR}
)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@ -1698,11 +1698,11 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
list(APPEND viewer_LIBRARIES
${BUGSPLAT_LIBRARIES}
)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
# Add resource files to the project.
set(viewer_RESOURCE_FILES
@ -2111,10 +2111,10 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
set_property(TARGET ${VIEWER_BINARY_NAME}
PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
@ -2244,15 +2244,16 @@ if (WINDOWS)
--actions=copy
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
stage_third_party_libs
@ -2312,15 +2313,16 @@ if (WINDOWS)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
DEPENDS
${VIEWER_BINARY_NAME}
@ -2428,11 +2430,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${GROWL_LIBRARY}
)
if (DEFINED ENV{BUGSPLAT_DB})
if (BUGSPLAT_DB)
target_link_libraries(${VIEWER_BINARY_NAME}
${BUGSPLAT_LIBRARIES}
)
endif (DEFINED ENV{BUGSPLAT_DB})
endif (BUGSPLAT_DB)
if (WINDOWS)
target_link_libraries(${VIEWER_BINARY_NAME}
@ -2479,15 +2481,16 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@ -2500,17 +2503,18 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
COMMAND ${PYTHON_EXECUTABLE}
ARGS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--actions=copy
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
${COPY_INPUT_DEPENDENCIES}
@ -2563,11 +2567,20 @@ if (DARWIN)
"${CMAKE_CURRENT_SOURCE_DIR}/Info-Firestorm.plist"
)
set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
# VIEWER_APP_EXECUTABLE was originally a prediction of the executable
# pathname that would result from running viewer_manifest.py, but CMake
# complained that there was no rule to make that executable. Try using the
# existing target.
set(VIEWER_APP_EXECUTABLE "${VIEWER_BINARY_NAME}")
set(VIEWER_APP_DSYM "${VIEWER_APP_EXECUTABLE}.dSYM")
set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
configure_file(
# <FS:CR> Use Firestorm plist
#"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
"${CMAKE_CURRENT_SOURCE_DIR}/Info-Firestorm.plist"
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
"${VIEWER_APP_BUNDLE}/Contents/Info.plist"
)
add_custom_command(
@ -2578,15 +2591,16 @@ if (DARWIN)
--actions=copy
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
--grid=${GRID}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
"--channel=${VIEWER_CHANNEL}"
--configuration=${CMAKE_CFG_INTDIR}
--dest=${VIEWER_APP_BUNDLE}
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${VIEWER_BINARY_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@ -2611,15 +2625,16 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
"--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
--grid=${GRID}
"--channel=${VIEWER_CHANNEL}"
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${VIEWER_APP_BUNDLE}
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
${SIGNING_SETTING}
DEPENDS
@ -2632,64 +2647,149 @@ if (INSTALL)
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
endif (INSTALL)
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
set(SYMBOL_SEARCH_DIRS "")
# Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
if (WINDOWS)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-windows-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
# 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_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
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_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-linux-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
set(VIEWER_EXE_GLOBS "do-not-directly-run-firestorm-bin SLPlugin")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
endif (LINUX)
# 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 BUGSPLAT_DB)
# 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 mac-crash-logger")
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-firestorm-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)
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_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}")
if (WINDOWS OR LINUX)
add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
endif (WINDOWS OR LINUX)
add_dependencies(llpackage generate_breakpad_symbols)
## add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
if (WINDOWS OR LINUX)
add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
endif (WINDOWS OR LINUX)
else (NOT BUGSPLAT_DB)
# BugSplat symbol-file generation
if (WINDOWS)
# Just pack up a tarball containing only the .pdb file for the
# executable. Because we intend to use cygwin tar, we must render
# VIEWER_SYMBOL_FILE in cygwin path syntax.
execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
# Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
# testing a string suffix is painful enough in CMake language that
# we'll continue assuming it until forced to generalize.
COMMAND "tar"
ARGS
"cjf"
"${VIEWER_SYMBOL_FILE_CYGWIN}"
"secondlife-bin.pdb"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
)
add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_BINARY_NAME}")
add_dependencies(generate_symbols "${VIEWER_BINARY_NAME}")
endif (WINDOWS)
if (DARWIN)
# Have to run dsymutil first, then pack up the resulting .dSYM directory
add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
COMMAND "dsymutil"
ARGS
"${VIEWER_APP_EXECUTABLE}"
DEPENDS "${VIEWER_APP_EXECUTABLE}"
COMMENT "Generating ${VIEWER_APP_DSYM}"
)
add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
add_dependencies(dsym_generate "${VIEWER_APP_EXECUTABLE}")
add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
# See above comments about "tar ...j"
COMMAND "tar"
ARGS
"cjf"
"${VIEWER_SYMBOL_FILE}"
"-C"
"${VIEWER_APP_DSYM}/.."
"${product}.dSYM"
DEPENDS "${VIEWER_APP_DSYM}"
COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
)
add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
add_dependencies(dsym_tarball dsym_generate)
add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
COMMAND "zip"
ARGS
"-r"
"${VIEWER_APP_XCARCHIVE}"
"."
WORKING_DIRECTORY "${VIEWER_APP_DSYM}/.."
DEPENDS "${VIEWER_APP_DSYM}"
COMMENT "Generating xcarchive.zip for upload to BugSplat"
)
add_custom_target(dsym_xcarchive DEPENDS "${VIEWER_APP_XCARCHIVE}")
add_dependencies(dsym_xcarchive dsym_generate)
# Have to create a stamp file, and depend on it, to force CMake to run
# the cleanup step.
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
COMMAND rm -rf "${VIEWER_APP_DSYM}"
COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_APP_XCARCHIVE}"
COMMENT "Cleaning up dSYM"
)
add_custom_target(generate_symbols DEPENDS
"${VIEWER_APP_DSYM}"
"${VIEWER_SYMBOL_FILE}"
"${VIEWER_APP_XCARCHIVE}"
"${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
)
add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
endif (DARWIN)
if (LINUX)
# TBD
endif (LINUX)
endif (NOT BUGSPLAT_DB)
# for both BUGSPLAT_DB and Breakpad
add_dependencies(llpackage generate_symbols)
endif ()
if (LL_TESTS)

View File

@ -69,6 +69,25 @@
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
// Call constructViewer() first so our logging subsystem is in place. This
// risks missing crashes in the LLAppViewerMacOSX constructor, but for
// present purposes it's more important to get the startup sequence
// properly logged.
// Someday I would like to modify the logging system so that calls before
// it's initialized are cached in a std::ostringstream and then, once it's
// initialized, "played back" into whatever handlers have been set up.
constructViewer();
#if defined(LL_BUGSPLAT)
// Engage BugsplatStartupManager *before* calling initViewer() to handle
// any crashes during initialization.
// https://www.bugsplat.com/docs/platforms/os-x#initialization
[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
[BugsplatStartupManager sharedManager].askUserDetails = NO;
[BugsplatStartupManager sharedManager].delegate = self;
[[BugsplatStartupManager sharedManager] start];
#endif
frameTimer = nil;
[self languageUpdated];
@ -86,14 +105,6 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
// [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
#if defined(LL_BUGSPLAT)
// https://www.bugsplat.com/docs/platforms/os-x#initialization
[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
[BugsplatStartupManager sharedManager].askUserDetails = NO;
[BugsplatStartupManager sharedManager].delegate = self;
[[BugsplatStartupManager sharedManager] start];
#endif
}
- (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
@ -215,25 +226,75 @@
- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("Reached applicationLogForBugsplatStartupManager");
// Apparently this override method only contributes the User Description
// field of BugSplat's All Crashes table. Despite the method name, it
// would seem to be a bad place to try to stuff all of SecondLife.log.
return [NSString stringWithCString:getFatalMessage().c_str()
CrashMetadata& meta(CrashMetadata_instance());
// As of BugsplatMac 1.0.6, userName and userEmail properties are now
// exposed by the BugsplatStartupManager. Set them here, since the
// defaultUserNameForBugsplatStartupManager and
// defaultUserEmailForBugsplatStartupManager methods are called later, for
// the *current* run, rather than for the previous crashed run whose crash
// report we are about to send.
infos("applicationLogForBugsplatStartupManager setting userName = '" +
meta.agentFullname + '"');
bugsplatStartupManager.userName =
[NSString stringWithCString:meta.agentFullname.c_str()
encoding:NSUTF8StringEncoding];
// Use the email field for OS version, just as we do on Windows, until
// BugSplat provides more metadata fields.
infos("applicationLogForBugsplatStartupManager setting userEmail = '" +
meta.OSInfo + '"');
bugsplatStartupManager.userEmail =
[NSString stringWithCString:meta.OSInfo.c_str()
encoding:NSUTF8StringEncoding];
// This strangely-named override method's return value contributes the
// User Description metadata field.
infos("applicationLogForBugsplatStartupManager -> '" + meta.fatalMessage + "'");
return [NSString stringWithCString:meta.fatalMessage.c_str()
encoding:NSUTF8StringEncoding];
}
- (NSString *)applicationKeyForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason {
// TODO: exceptionName, exceptionReason
// Windows sends location within region as well, but that's because
// BugSplat for Windows intercepts crashes during the same run, and that
// information can be queried once. On the Mac, any metadata we have is
// written (and rewritten) to the static_debug_info.log file that we read
// at the start of the next viewer run. It seems ridiculously expensive to
// rewrite that file on every frame in which the avatar moves.
std::string regionName(CrashMetadata_instance().regionName);
infos("applicationKeyForBugsplatStartupManager -> '" + regionName + "'");
return [NSString stringWithCString:regionName.c_str()
encoding:NSUTF8StringEncoding];
}
- (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
std::string agentFullname(CrashMetadata_instance().agentFullname);
infos("defaultUserNameForBugsplatStartupManager -> '" + agentFullname + "'");
return [NSString stringWithCString:agentFullname.c_str()
encoding:NSUTF8StringEncoding];
}
- (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
// Use the email field for OS version, just as we do on Windows, until
// BugSplat provides more metadata fields.
std::string OSInfo(CrashMetadata_instance().OSInfo);
infos("defaultUserEmailForBugsplatStartupManager -> '" + OSInfo + "'");
return [NSString stringWithCString:OSInfo.c_str()
encoding:NSUTF8StringEncoding];
}
- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("Reached bugsplatStartupManagerWillSendCrashReport");
infos("bugsplatStartupManagerWillSendCrashReport");
}
- (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
// We get the *old* log file pathname (for SecondLife.old) because it's on
// the run *following* the crash that BugsplatStartupManager notices that
// the previous run crashed and calls this override. By that time, we've
// already renamed SecondLife.log to SecondLife.old.
std::string logfile = getOldLogFilePathname();
std::string logfile = CrashMetadata_instance().logFilePathname;
// Still to do:
// userSettingsPathname
// staticDebugPathname
// but the BugsplatMac version 1.0.5 BugsplatStartupManagerDelegate API
// doesn't yet provide a way to attach more than one file.
NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
encoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
@ -244,7 +305,7 @@
[[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
attachmentData:data
contentType:@"text/plain"];
infos("attachmentForBugsplatStartupManager: attaching " + logfile);
infos("attachmentForBugsplatStartupManager attaching " + logfile);
return attachment;
}

View File

@ -788,6 +788,22 @@ LLAppViewer::LLAppViewer()
//
LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple());
// Under some circumstances we want to read the static_debug_info.log file
// from the previous viewer run between this constructor call and the
// init() call, which will overwrite the static_debug_info.log file for
// THIS run. So setDebugFileNames() early.
#if LL_BUGSPLAT
// MAINT-8917: don't create a dump directory just for the
// static_debug_info.log file
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
#else // ! LL_BUGSPLAT
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
#endif // ! LL_BUGSPLAT
mDumpPath = logdir;
setMiniDumpDir(logdir);
setDebugFileNames(logdir);
}
LLAppViewer::~LLAppViewer()
@ -959,19 +975,6 @@ bool LLAppViewer::init()
initMaxHeapSize() ;
LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
#if LL_BUGSPLAT
// MAINT-8917: don't create a dump directory just for the
// static_debug_info.log file
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
#else // ! LL_BUGSPLAT
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
#endif // ! LL_BUGSPLAT
mDumpPath = logdir;
setMiniDumpDir(logdir);
logdir += gDirUtilp->getDirDelimiter();
setDebugFileNames(logdir);
// Although initLoggingAndGetLastDuration() is the right place to mess with
// setFatalFunction(), we can't query gSavedSettings until after
@ -3630,14 +3633,11 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
? getStaticDebugFile()
: getDynamicDebugFile() );
LL_INFOS() << "Opening debug file " << *debug_filename << LL_ENDL;
llofstream out_file(debug_filename->c_str());
LL_INFOS() << "Writing debug file " << *debug_filename << LL_ENDL;
llofstream out_file(debug_filename->c_str());
isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file)
: LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file);
out_file.close();
}
LLSD LLAppViewer::getViewerInfo() const

View File

@ -24,14 +24,30 @@
#include <string>
void constructViewer();
bool initViewer();
void handleUrl(const char* url_utf8);
bool pumpMainLoop();
void handleQuit();
void cleanupViewer();
std::string getOldLogFilePathname();
std::string getFatalMessage();
std::string getAgentFullname();
void infos(const std::string& message);
// This struct is malleable; it only serves as a way to convey a number of
// fields from llappviewermacosx.cpp's CrashMetadata_instance() function to the
// consuming functions in llappdelegate-objc.mm. As long as both those sources
// are compiled with this same header, the content and order of CrashMetadata
// can change as needed.
struct CrashMetadata
{
std::string logFilePathname;
std::string userSettingsPathname;
std::string staticDebugPathname;
std::string OSInfo;
std::string agentFullname;
std::string regionName;
std::string fatalMessage;
};
CrashMetadata& CrashMetadata_instance();
#endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */

View File

@ -39,6 +39,7 @@
#include "llappviewermacosx-for-objc.h"
#include "llwindowmacosx-objc.h"
#include "llcommandlineparser.h"
#include "llsdserialize.h"
#include "llviewernetwork.h"
#include "llviewercontrol.h"
@ -53,6 +54,7 @@
#endif
#include <vector>
#include <exception>
#include <fstream>
#include "lldir.h"
#include <signal.h>
@ -84,7 +86,7 @@ static void exceptionTerminateHandler()
gOldTerminateHandler(); // call old terminate() handler
}
bool initViewer()
void constructViewer()
{
// Set the working dir to <bundle>/Contents/Resources
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
@ -100,18 +102,20 @@ bool initViewer()
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
}
bool initViewer()
{
bool ok = gViewerAppPtr->init();
if(!ok)
{
LL_WARNS() << "Application init failed." << LL_ENDL;
}
else if (!gHandleSLURL.empty())
{
dispatchUrl(gHandleSLURL);
gHandleSLURL = "";
}
else if (!gHandleSLURL.empty())
{
dispatchUrl(gHandleSLURL);
gHandleSLURL = "";
}
return ok;
}
@ -150,19 +154,66 @@ void cleanupViewer()
gViewerAppPtr = NULL;
}
std::string getOldLogFilePathname()
// The BugsplatMac API is structured as a number of different method
// overrides, each returning a different piece of metadata. But since we
// obtain such metadata by opening and parsing a file, it seems ridiculous to
// reopen and reparse it for every individual string desired. What we want is
// to open and parse the file once, retaining the data for subsequent
// requests. That's why this is an LLSingleton.
// Another approach would be to provide a function that simply returns
// CrashMetadata, storing the struct in LLAppDelegate, but nat doesn't know
// enough Objective-C++ to code that. We'd still have to detect which of the
// method overrides is called first so that the results are order-insensitive.
class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMetadataSingleton>
{
return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");
LLSINGLETON(CrashMetadataSingleton);
// convenience method to log each metadata field retrieved by constructor
std::string get_metadata(const LLSD& info, const LLSD::String& key) const
{
std::string data(info[key].asString());
LL_INFOS() << " " << key << "='" << data << "'" << LL_ENDL;
return data;
}
};
// Populate the fields of our public base-class struct.
CrashMetadataSingleton::CrashMetadataSingleton()
{
// Note: we depend on being able to read the static_debug_info.log file
// from the *previous* run before we overwrite it with the new one for
// *this* run. LLAppViewer initialization must happen in the Right Order.
staticDebugPathname = *gViewerAppPtr->getStaticDebugFile();
std::ifstream static_file(staticDebugPathname);
LLSD info;
if (! static_file.is_open())
{
LL_INFOS() << "Can't open '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
{
LL_INFOS() << "Can't parse '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else
{
LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
logFilePathname = get_metadata(info, "SLLog");
userSettingsPathname = get_metadata(info, "SettingsFilename");
OSInfo = get_metadata(info, "OSInfo");
agentFullname = get_metadata(info, "LoginName");
// Translate underscores back to spaces
LLStringUtil::replaceChar(agentFullname, '_', ' ');
regionName = get_metadata(info, "CurrentRegion");
fatalMessage = get_metadata(info, "FatalMessage");
}
}
std::string getFatalMessage()
// Avoid having to compile all of our LLSingleton machinery in Objective-C++.
CrashMetadata& CrashMetadata_instance()
{
return LLError::getFatalMessage();
}
std::string getAgentFullname()
{
return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string();
return CrashMetadataSingleton::instance();
}
void infos(const std::string& message)

View File

@ -44,6 +44,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llappviewer.h"
#include "llavatarrenderinfoaccountant.h"
#include "llcallingcard.h"
#include "llcommandhandler.h"
@ -113,6 +114,18 @@ typedef std::map<std::string, std::string> CapabilityMap;
static void log_capabilities(const CapabilityMap &capmap);
namespace
{
void newRegionEntry(LLViewerRegion& region)
{
LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
gDebugInfo["CurrentRegion"] = region.getName();
LLAppViewer::instance()->writeDebugInfo();
}
} // anonymous namespace
// support for secondlife:///app/region/{REGION} SLapps
// N.B. this is defined to work exactly like the classic secondlife://{REGION}
// However, the later syntax cannot support spaces in the region name because
@ -258,6 +271,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
// After a few attempts, continue login. But keep trying to get the caps:
if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
@ -378,6 +394,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
break; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
LLSD capabilityNames = LLSD::emptyArray();
buildCapabilityNames(capabilityNames);

View File

@ -226,11 +226,10 @@ class ViewerManifest(LLManifest,FSViewerManifest):
"Address Size":self.address_size,
"Update Service":"https://update.secondlife.com/update",
}
try:
build_data_dict["BugSplat DB"] = os.environ["BUGSPLAT_DB"]
except KeyError:
# skip the assignment if there's no BUGSPLAT_DB variable
pass
# Only store this if it's both present and non-empty
bugsplat_db = self.args.get('bugsplat')
if bugsplat_db:
build_data_dict["BugSplat DB"] = bugsplat_db
build_data_dict = self.finish_build_data_dict(build_data_dict)
with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
json.dump(build_data_dict,build_data_handle)
@ -664,14 +663,15 @@ class WindowsManifest(ViewerManifest):
self.path("libhunspell.dll")
# BugSplat
if(self.address_size == 64):
self.path("BsSndRpt64.exe")
self.path("BugSplat64.dll")
self.path("BugSplatRc64.dll")
else:
self.path("BsSndRpt.exe")
self.path("BugSplat.dll")
self.path("BugSplatRc.dll")
if self.args.get('bugsplat'):
if(self.address_size == 64):
self.path("BsSndRpt64.exe")
self.path("BugSplat64.dll")
self.path("BugSplatRc64.dll")
else:
self.path("BsSndRpt.exe")
self.path("BugSplat.dll")
self.path("BugSplatRc.dll")
# Growl
self.path("growl.dll")
@ -1166,39 +1166,6 @@ class DarwinManifest(ViewerManifest):
# if ("package" in self.args['actions'] or
# "unpacked" in self.args['actions']):
# # only if we're engaging BugSplat
# if "BUGSPLAT_DB" in os.environ:
# # Create a symbol archive BEFORE stripping the
# # binary.
# self.run_command(['dsymutil', exepath])
# # This should produce a Second Life.dSYM bundle directory.
# try:
# # Now pretend we're Xcode making a .xcarchive file.
# # Put it as a sibling of the top-level .app.
# # From "Dave" at BugSplat support:
# # "More from our Mac lead: I think zipping
# # a folder containing the binary and
# # symbols would be sufficient. Assuming
# # symbol files are created with CMake. I'm
# # not sure if CMake strips symbols into
# # separate files at build time, and if so
# # they're in a supported format."
# xcarchive = os.path.join(parentdir,
# exename + '.xcarchive.zip')
# with zipfile.ZipFile(xcarchive, 'w',
# compression=zipfile.ZIP_DEFLATED) as zf:
# print "Creating {}".format(xcarchive)
# for base, dirs, files in os.walk(here):
# for fn in files:
# fullfn = os.path.join(base, fn)
# relfn = os.path.relpath(fullfn, here)
# print " {}".format(relfn)
# zf.write(fullfn, relfn)
# finally:
# # Whether or not we were able to create the
# # .xcarchive file, clean up the .dSYM bundle
# shutil.rmtree(self.dst_path_of(exename + '.dSYM'))
# # NOTE: the -S argument to strip causes it to keep
# # enough info for annotated backtraces (i.e. function
# # names in the crash log). 'strip' with no arguments
@ -1214,13 +1181,11 @@ class DarwinManifest(ViewerManifest):
# # runs the executable, instead of launching the app)
# Info["CFBundleExecutable"] = exename
# Info["CFBundleIconFile"] = viewer_icon
# try:
# bugsplat_db = self.args.get('bugsplat')
# if bugsplat_db:
# # https://www.bugsplat.com/docs/platforms/os-x#configuration
# Info["BugsplatServerURL"] = \
# "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
# except KeyError:
# # skip the assignment if there's no BUGSPLAT_DB variable
# pass
# "https://{}.bugsplat.com/".format(bugsplat_db)
# self.put_in_file(
# plistlib.writePlistToString(Info),
# os.path.basename(Info_plist),
@ -1233,7 +1198,8 @@ class DarwinManifest(ViewerManifest):
# # Remember where we parked this car.
# CEF_framework = self.dst_path_of(CEF_framework)
# self.path2basename(relpkgdir, "BugsplatMac.framework")
# if self.args.get('bugsplat'):
# self.path2basename(relpkgdir, "BugsplatMac.framework")
# with self.prefix(dst="Resources"):
# # defer cross-platform file copies until we're in the right
@ -2461,4 +2427,8 @@ def symlinkf(src, dst):
# </FS:Ansariel> Added back for Mac compatibility reason
if __name__ == "__main__":
main()
extra_arguments = [
dict(name='bugsplat', description="""BugSplat database to which to post crashes,
if BugSplat crash reporting is desired""", default=''),
]
main(extra=extra_arguments)