Skip to content
Snippets Groups Projects
Commit c5f618d0 authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

SL-821: Move Windows BugSplat engagement from llcommon to newview.

Use WSTRINGIZE(), LL_TO_WSTRING(), wstringize() to produce required wide
strings. Use a lambda for callback that sends log file; use LLDir, if set, to
find the log file.

Introduce BUGSPLAT CMake variable to allow suppressing BugSplat.
Make BUGSPLAT CMake variable set LL_BUGSPLAT for C++ compilations.

Set viewer version macros on llappviewerwin32.cpp, llappviewerlinux.cpp and
llappdelegate-objc.mm -- because BugSplat needs the viewer version data, and
because the macOS BugSplat hook is engaged in an Objective-C++ function we
override in the app delegate.
parent c45fc5a3
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES ...@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
Audio.cmake Audio.cmake
BerkeleyDB.cmake BerkeleyDB.cmake
Boost.cmake Boost.cmake
bugsplat.cmake
BuildVersion.cmake BuildVersion.cmake
CEFPlugin.cmake CEFPlugin.cmake
CEFPlugin.cmake CEFPlugin.cmake
......
include(Prebuilt) # BUGSPLAT can be set when launching the make using the argument -DBUGSPLAT:BOOL=ON
# When building using proprietary binaries though (i.e. having access to LL private servers),
# we always build with BUGSPLAT.
# Open source devs should use the -DBUGSPLAT:BOOL=ON then if they want to
# build with BugSplat, whether they are using USESYSTEMLIBS or not.
if (INSTALL_PROPRIETARY)
set(BUGSPLAT ON CACHE BOOL "Using BugSplat crash reporting library.")
endif (INSTALL_PROPRIETARY)
set(BUGSPLAT_FIND_QUIETLY ON) if (BUGSPLAT)
set(BUGSPLAT_FIND_REQUIRED ON) if (USESYSTEMLIBS)
set(BUGSPLAT_FIND_QUIETLY ON)
set(BUGSPLAT_FIND_REQUIRED ON)
include(FindBUGSPLAT)
else (USESYSTEMLIBS)
include(Prebuilt)
use_prebuilt_binary(bugsplat)
if (WINDOWS)
set(BUGSPLAT_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
)
elseif (DARWIN)
find_library(BUGSPLAT_LIBRARIES BugsplatMac
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
else (WINDOWS)
if (USESYSTEMLIBS) endif (WINDOWS)
include(FindBUGSPLAT) set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
else (USESYSTEMLIBS) endif (USESYSTEMLIBS)
use_prebuilt_binary(bugsplat) endif (BUGSPLAT)
if (WINDOWS)
set(BUGSPLAT_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
)
elseif (DARWIN)
else (WINDOWS)
endif (WINDOWS)
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
endif (USESYSTEMLIBS)
...@@ -13,7 +13,6 @@ include(GoogleBreakpad) ...@@ -13,7 +13,6 @@ include(GoogleBreakpad)
include(Copy3rdPartyLibs) include(Copy3rdPartyLibs)
include(ZLIB) include(ZLIB)
include(URIPARSER) include(URIPARSER)
include(BuildVersion)
include_directories( include_directories(
${EXPAT_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS}
...@@ -254,14 +253,7 @@ set(llcommon_HEADER_FILES ...@@ -254,14 +253,7 @@ set(llcommon_HEADER_FILES
) )
set_source_files_properties(${llcommon_HEADER_FILES} set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE PROPERTIES HEADER_FILE_ONLY TRUE)
)
# bring in version information for BugSplat crash reporting
set_source_files_properties(${llcommon_SOURCE_FILES}
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
)
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
......
...@@ -49,20 +49,6 @@ ...@@ -49,20 +49,6 @@
#include "google_breakpad/exception_handler.h" #include "google_breakpad/exception_handler.h"
#include "stringize.h" #include "stringize.h"
#include "llcleanup.h" #include "llcleanup.h"
#include "BugSplat.h"
// TESTING ONLY - REMOVE FOR PRODUCTION
// (Want to only invoke BugSplat crash reporting in the same way we did for Breakpad - for Release viewers
// but need to test here in a ReleaseWithDebugInfo environment)
#if BUGSPLAT_ENABLED
#define LL_SEND_CRASH_REPORTS 1
#endif
// BugSplat crash reporting tool - http://bugsplat.com
#if BUGSPLAT_ENABLED
bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2);
MiniDmpSender *gBugSplatSender;
#endif
// //
// Signal handling // Signal handling
...@@ -399,26 +385,6 @@ void EnableCrashingOnCrashes() ...@@ -399,26 +385,6 @@ void EnableCrashingOnCrashes()
} }
#endif #endif
#if BUGSPLAT_ENABLED
bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
{
switch (nCode)
{
case MDSCB_EXCEPTIONCODE:
{
// send the main viewer log file (Clearly a temporary hack since we don't have access to the gDir*** set of functions in newview
const std::string appdata = std::string(getenv("APPDATA"));
const std::string logfile = appdata + "\\SecondLife\\logs\\Secondlife.log";
const std::wstring wide_logfile(logfile.begin(), logfile.end());
gBugSplatSender->sendAdditionalFile((const __wchar_t *)wide_logfile.c_str());
}
break;
}
return false;
}
#endif
void LLApp::setupErrorHandling(bool second_instance) void LLApp::setupErrorHandling(bool second_instance)
{ {
// Error handling is done by starting up an error handling thread, which just sleeps and // Error handling is done by starting up an error handling thread, which just sleeps and
...@@ -427,25 +393,6 @@ void LLApp::setupErrorHandling(bool second_instance) ...@@ -427,25 +393,6 @@ void LLApp::setupErrorHandling(bool second_instance)
#if LL_WINDOWS #if LL_WINDOWS
#if LL_SEND_CRASH_REPORTS #if LL_SEND_CRASH_REPORTS
#if BUGSPLAT_ENABLED
// TODOCP: populate these fields correctly
static const wchar_t *bugdb_name = L"second_life_callum_test";
// build (painfully) the app/channel name
#define stringize_inner(x) L#x
#define stringize_outer(x) stringize_inner(x)
std::wstring app_name(stringize_outer(LL_VIEWER_CHANNEL));
// build in real app version now we leveraged CMake to build in BuildVersion.cmake into LLCommon
wchar_t version_string[MAX_STRING];
wsprintf(version_string, L"%d.%d.%d.%d", LL_VIEWER_VERSION_MAJOR, LL_VIEWER_VERSION_MINOR, LL_VIEWER_VERSION_PATCH, LL_VIEWER_VERSION_BUILD);
gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name.c_str(), (const __wchar_t *)version_string, NULL);
gBugSplatSender->setCallback(BugSplatExceptionCallback);
#else
EnableCrashingOnCrashes(); EnableCrashingOnCrashes();
// This sets a callback to handle w32 signals to the console window. // This sets a callback to handle w32 signals to the console window.
...@@ -507,9 +454,8 @@ void LLApp::setupErrorHandling(bool second_instance) ...@@ -507,9 +454,8 @@ void LLApp::setupErrorHandling(bool second_instance)
mExceptionHandler->set_handle_debug_exceptions(true); mExceptionHandler->set_handle_debug_exceptions(true);
} }
} }
#endif // BUGSPLAT_ENABLED #endif
#endif // LL_SEND_CRASH_REPORTS #else
#else // not LL_WINDOWS
// //
// Start up signal handling. // Start up signal handling.
// //
...@@ -570,7 +516,7 @@ void LLApp::setupErrorHandling(bool second_instance) ...@@ -570,7 +516,7 @@ void LLApp::setupErrorHandling(bool second_instance)
} }
#endif #endif
#endif // LL_WINDOWS #endif
startErrorThread(); startErrorThread();
} }
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <map> #include <map>
#include "llrun.h" #include "llrun.h"
#include "llsd.h" #include "llsd.h"
// Forward declarations // Forward declarations
template <typename Type> class LLAtomic32; template <typename Type> class LLAtomic32;
typedef LLAtomic32<U32> LLAtomicU32; typedef LLAtomic32<U32> LLAtomicU32;
...@@ -40,14 +39,6 @@ class LLLiveFile; ...@@ -40,14 +39,6 @@ class LLLiveFile;
#include <signal.h> #include <signal.h>
#endif #endif
// first version of Bugsplat (http://bugsplat.com) crash reporting tool
// is only supported on Windows - macOS to follow.
#define BUGSPLAT_ENABLED LL_WINDOWS
#if BUGSPLAT_ENABLED
class __declspec(dllexport) MiniDmpSender;
#endif
typedef void (*LLAppErrorHandler)(); typedef void (*LLAppErrorHandler)();
#if !LL_WINDOWS #if !LL_WINDOWS
...@@ -325,6 +316,7 @@ class LL_COMMON_API LLApp ...@@ -325,6 +316,7 @@ class LL_COMMON_API LLApp
google_breakpad::ExceptionHandler * mExceptionHandler; google_breakpad::ExceptionHandler * mExceptionHandler;
#if !LL_WINDOWS #if !LL_WINDOWS
friend void default_unix_signal_handler(int signum, siginfo_t *info, void *); friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
#endif #endif
......
...@@ -1354,6 +1354,11 @@ if (DARWIN) ...@@ -1354,6 +1354,11 @@ if (DARWIN)
# This should be compiled with the viewer. # This should be compiled with the viewer.
LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
set_source_files_properties(
llappdelegate-objc.mm
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
)
find_library(AGL_LIBRARY AGL) find_library(AGL_LIBRARY AGL)
find_library(APPKIT_LIBRARY AppKit) find_library(APPKIT_LIBRARY AppKit)
...@@ -1366,6 +1371,7 @@ if (DARWIN) ...@@ -1366,6 +1371,7 @@ if (DARWIN)
${AGL_LIBRARY} ${AGL_LIBRARY}
${IOKIT_LIBRARY} ${IOKIT_LIBRARY}
${COREAUDIO_LIBRARY} ${COREAUDIO_LIBRARY}
${BUGSPLAT_LIBRARIES}
) )
# Add resource files to the project. # Add resource files to the project.
...@@ -1393,6 +1399,11 @@ endif (DARWIN) ...@@ -1393,6 +1399,11 @@ endif (DARWIN)
if (LINUX) if (LINUX)
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
set_source_files_properties(
llappviewerlinux.cpp
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
)
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
...@@ -1409,6 +1420,11 @@ if (WINDOWS) ...@@ -1409,6 +1420,11 @@ if (WINDOWS)
llappviewerwin32.cpp llappviewerwin32.cpp
llwindebug.cpp llwindebug.cpp
) )
set_source_files_properties(
llappviewerwin32.cpp
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
)
list(APPEND viewer_HEADER_FILES list(APPEND viewer_HEADER_FILES
llappviewerwin32.h llappviewerwin32.h
...@@ -1692,6 +1708,11 @@ if (SDL_FOUND) ...@@ -1692,6 +1708,11 @@ if (SDL_FOUND)
) )
endif (SDL_FOUND) endif (SDL_FOUND)
if (BUGSPLAT)
set_property(TARGET ${VIEWER_BINARY_NAME}
PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (BUGSPLAT)
# add package files # add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py) ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
...@@ -1790,7 +1811,7 @@ if (WINDOWS) ...@@ -1790,7 +1811,7 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
) )
endif (FMODEX) endif (FMODEX)
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat
COMMAND ${PYTHON_EXECUTABLE} COMMAND ${PYTHON_EXECUTABLE}
......
...@@ -66,8 +66,18 @@ ...@@ -66,8 +66,18 @@
#endif #endif
#include "stringize.h" #include "stringize.h"
#include "lldir.h"
#include <exception> #include <exception>
// Bugsplat (http://bugsplat.com) crash reporting tool
#ifdef LL_BUGSPLAT
#include "BugSplat.h"
// FIXME: need a production BugSplat database name
static const wchar_t *bugdb_name = L"second_life_callum_test";
#endif
namespace namespace
{ {
void (*gOldTerminateHandler)() = NULL; void (*gOldTerminateHandler)() = NULL;
...@@ -495,15 +505,46 @@ bool LLAppViewerWin32::init() ...@@ -495,15 +505,46 @@ bool LLAppViewerWin32::init()
LLWinDebug::instance(); LLWinDebug::instance();
#endif #endif
#if LL_WINDOWS
#if LL_SEND_CRASH_REPORTS #if LL_SEND_CRASH_REPORTS
#if ! defined(LL_BUGSPLAT)
LLAppViewer* pApp = LLAppViewer::instance(); LLAppViewer* pApp = LLAppViewer::instance();
pApp->initCrashReporting(); pApp->initCrashReporting();
#endif #else // LL_BUGSPLAT
#endif
std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
LL_VIEWER_VERSION_MINOR << '.' <<
LL_VIEWER_VERSION_PATCH << '.' <<
LL_VIEWER_VERSION_BUILD));
auto sender = new MiniDmpSender(
bugdb_name, LL_TO_WSTRING(LL_VIEWER_CHANNEL), version_string.c_str(), nullptr);
sender->setCallback(
[sender](unsigned int nCode, void* lpVal1, void* lpVal2)
{
// If we haven't yet initialized LLDir, don't bother trying to
// find our log file.
// Alternatively -- if we might encounter trouble trying to query
// LLDir during crash cleanup -- consider making gDirUtilp an
// LLPounceable, and attach a callback that stores the pathname to
// the log file here.
if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
{
// send the main viewer log file
// widen to wstring, then pass c_str()
sender->sendAdditionalFile(
wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
}
return false;
});
LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
<< version_string << ')' << LL_ENDL;
#endif // LL_BUGSPLAT
#endif // LL_SEND_CRASH_REPORTS
bool success = LLAppViewer::init(); bool success = LLAppViewer::init();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment