From 803b75a718833ccf236f00b425faff4eaf0f29cb Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Wed, 18 Oct 2017 18:36:10 -0700
Subject: First version that builds with a dummy BugSplay call in llapp.cpp

---
 autobuild.xml                      | 42 ++++++++++++++++++++++++++++++++++++++
 indra/cmake/Copy3rdPartyLibs.cmake |  3 +++
 indra/cmake/bugsplat.cmake         | 20 ++++++++++++++++++
 indra/llcommon/CMakeLists.txt      |  3 +++
 indra/llcommon/llapp.cpp           | 12 +++++++++++
 indra/newview/viewer_manifest.py   | 19 ++++++++++++-----
 6 files changed, 94 insertions(+), 5 deletions(-)
 create mode 100644 indra/cmake/bugsplat.cmake

diff --git a/autobuild.xml b/autobuild.xml
index f8daa6a418..e12f7cbc1d 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -225,6 +225,48 @@
         <key>version</key>
         <string>1.57</string>
       </map>
+      <key>bugsplat</key>
+      <map>
+        <key>copyright</key>
+        <string>Copyright 2003-2017, BugSplat</string>
+        <key>description</key>
+        <string>Bugsplat crash reporting package</string>
+        <key>license</key>
+        <string>Proprietary</string>
+        <key>license_file</key>
+        <string>LICENSES/BUGSPLAT_LICENSE.txt</string>
+        <key>name</key>
+        <string>bugsplat</string>
+        <key>platforms</key>
+        <map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>f01c3cbeeeedf9efaf111c7b51fc3e5b</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9929/48024/bugsplat-3.5.0.5-windows-509917.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+          <key>windows64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>6878c5ac26ee1a7b8126d1c9f052e059</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9928/48018/bugsplat-3.5.0.5-windows64-509917.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows64</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>3.5.0.5</string>
+      </map>
       <key>chardet</key>
       <map>
         <key>copyright</key>
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 5ccbe7d1d8..9238d232b8 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -39,6 +39,9 @@ if(WINDOWS)
         libeay32.dll
         glod.dll
         libhunspell.dll
+        BugSplat64.dll
+        BugSplatRc64.dll
+        BsSndRpt64.exe
         )
 
     if (FMODEX)
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
new file mode 100644
index 0000000000..6805465023
--- /dev/null
+++ b/indra/cmake/bugsplat.cmake
@@ -0,0 +1,20 @@
+include(Prebuilt)
+
+set(BUGSPLAT_FIND_QUIETLY ON)
+set(BUGSPLAT_FIND_REQUIRED ON)
+
+if (USESYSTEMLIBS)
+  include(FindBUGSPLAT)
+else (USESYSTEMLIBS)
+  use_prebuilt_binary(bugsplat)
+  if (WINDOWS)
+    set(BUGSPLAT_LIBRARIES 
+      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat64.lib
+      )
+  elseif (DARWIN)
+
+  else (WINDOWS)
+
+  endif (WINDOWS)
+  set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
+endif (USESYSTEMLIBS)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d9eb13d65a..50e262ae7a 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,6 +13,7 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
+include(BUGSPLAT)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -21,6 +22,7 @@ include_directories(
     ${ZLIB_INCLUDE_DIRS}
     ${BREAKPAD_INCLUDE_DIRECTORIES}
     ${URIPARSER_INCLUDE_DIRS}
+    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
@@ -291,6 +293,7 @@ target_link_libraries(
     ${BOOST_SYSTEM_LIBRARY}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     ${URIPARSER_LIBRARIES}
+    ${BUGSPLAT_LIBRARIES}
     )
 
 if (DARWIN)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6cc9e804d4..9dd9fc3c70 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -50,6 +50,10 @@
 #include "stringize.h"
 #include "llcleanup.h"
 
+#include "BugSplat.h"
+
+MiniDmpSender *mpSender;
+
 //
 // Signal handling
 //
@@ -151,6 +155,14 @@ void LLApp::commonCtor()
 	// (this is used to avoid allocating memory in the crash handler)
 	memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
 	mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
+
+
+	static const wchar_t *bugdb_name = L"second_life_callum_test";
+	static const wchar_t *app_name = L"SecondLifeViewer";
+	static const wchar_t *app_version = L"1.0.0";
+	mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+
 }
 
 LLApp::LLApp(LLErrorThread *error_thread) :
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 71e348db3f..7292f715b7 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -448,6 +448,11 @@ class WindowsManifest(ViewerManifest):
             # Hunspell
             self.path("libhunspell.dll")
 
+            # BugSplat
+            self.path("BsSndRpt64.exe")
+            self.path("BugSplat64.dll")
+            self.path("BugSplatRc64.dll")
+
             # For google-perftools tcmalloc allocator.
             try:
                 if self.args['configuration'].lower() == 'debug':
@@ -457,7 +462,6 @@ class WindowsManifest(ViewerManifest):
             except:
                 print "Skipping libtcmalloc_minimal.dll"
 
-
         self.path(src="licenses-win32.txt", dst="licenses.txt")
         self.path("featuretable.txt")
         self.path("ca-bundle.crt")
@@ -571,10 +575,15 @@ class WindowsManifest(ViewerManifest):
             self.path("zh-CN.pak")
             self.path("zh-TW.pak")
 
-            with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
-                self.path("libvlc.dll")
-                self.path("libvlccore.dll")
-                self.path("plugins/")
+        with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"):
+            self.path("libvlc.dll")
+            self.path("libvlccore.dll")
+            self.path("plugins/")
+
+        with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst=""):
+            self.path("BsSndRpt64.exe")
+            self.path("BugSplat64.dll")
+            self.path("BugSplatRc64.dll")
 
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
-- 
cgit v1.2.3


From e75b16f3584b76df706a470395383abf680eb87f Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Thu, 19 Oct 2017 11:34:36 -0700
Subject: First pass at adding BugSplat code to viewer and turning off existing
 (Google Breakpad) exception handling

---
 indra/llcommon/llapp.cpp | 76 +++++++++++++++++++++++++++++++++++++++---------
 indra/llcommon/llapp.h   | 10 ++++++-
 2 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 9dd9fc3c70..ea4a0fb59c 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -49,10 +49,20 @@
 #include "google_breakpad/exception_handler.h"
 #include "stringize.h"
 #include "llcleanup.h"
-
 #include "BugSplat.h"
 
-MiniDmpSender *mpSender;
+// 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
@@ -155,14 +165,6 @@ void LLApp::commonCtor()
 	// (this is used to avoid allocating memory in the crash handler)
 	memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
 	mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
-
-
-	static const wchar_t *bugdb_name = L"second_life_callum_test";
-	static const wchar_t *app_name = L"SecondLifeViewer";
-	static const wchar_t *app_version = L"1.0.0";
-	mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
-
-
 }
 
 LLApp::LLApp(LLErrorThread *error_thread) :
@@ -397,6 +399,42 @@ void EnableCrashingOnCrashes()
 }
 #endif
 
+#if BUGSPLAT_ENABLED
+bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
+{
+	switch (nCode)
+	{
+		case MDSCB_EXCEPTIONCODE:
+		{
+			EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1;
+			DWORD code = p ? p->ExceptionCode : 0;
+
+			// create some files in the %temp% directory and attach them
+			wchar_t cmdString[2 * MAX_PATH];
+			wchar_t filePath[MAX_PATH];
+			wchar_t tempPath[MAX_PATH];
+			GetTempPathW(MAX_PATH, tempPath);
+
+			wsprintf(filePath, L"%sfile1.txt", tempPath);
+			wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath);
+			_wsystem(cmdString);
+			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+
+			wsprintf(filePath, L"%sfile2.txt", tempPath);
+			wchar_t buf[_MAX_PATH];
+			gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH);
+
+			wsprintf(cmdString, L"echo Crash reporting is so clutch!  minidump path = %s > %s", buf, filePath);
+			_wsystem(cmdString);
+			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+		}
+		break;
+	}
+
+	return false;
+}
+#endif
+
 void LLApp::setupErrorHandling(bool second_instance)
 {
 	// Error handling is done by starting up an error handling thread, which just sleeps and
@@ -405,6 +443,17 @@ void LLApp::setupErrorHandling(bool second_instance)
 #if LL_WINDOWS
 
 #if LL_SEND_CRASH_REPORTS
+
+#if BUGSPLAT_ENABLED
+	// TODOCP: populate these fields correctly
+	static const wchar_t *bugdb_name = L"second_life_callum_test";
+	static const wchar_t *app_name = L"SecondLifeViewer";
+	static const wchar_t *app_version = L"1.0.0";
+	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+	gBugSplatSender->setCallback(BugSplatExceptionCallback);
+#else
+
 	EnableCrashingOnCrashes();
 
 	// This sets a callback to handle w32 signals to the console window.
@@ -466,8 +515,9 @@ void LLApp::setupErrorHandling(bool second_instance)
 			mExceptionHandler->set_handle_debug_exceptions(true);
 		}
 	}
-#endif
-#else
+#endif  // BUGSPLAT_ENABLED
+#endif	// LL_SEND_CRASH_REPORTS
+#else	// not LL_WINDOWS
 	//
 	// Start up signal handling.
 	//
@@ -528,7 +578,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 	}
 #endif
 
-#endif
+#endif // LL_WINDOWS
 	startErrorThread();
 }
 
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index acd829d864..5a4b7f13df 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -30,6 +30,7 @@
 #include <map>
 #include "llrun.h"
 #include "llsd.h"
+
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -39,6 +40,14 @@ class LLLiveFile;
 #include <signal.h>
 #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)();
 
 #if !LL_WINDOWS
@@ -316,7 +325,6 @@ private:
 	
 	google_breakpad::ExceptionHandler * mExceptionHandler;
 
-
 #if !LL_WINDOWS
 	friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 #endif
-- 
cgit v1.2.3


From 6cbb00fe85df8cb01c3a979dbdf2c0354e7bfa4d Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Thu, 19 Oct 2017 18:35:00 -0700
Subject: Differentiate between 32/64 bit windows builds for build systewm
 (BugsSplat enforces specifc names that vary across bitness)

---
 autobuild.xml                    |  8 ++++----
 indra/cmake/bugsplat.cmake       |  2 +-
 indra/newview/viewer_manifest.py | 16 ++++++++--------
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index e12f7cbc1d..ee052de5e6 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f01c3cbeeeedf9efaf111c7b51fc3e5b</string>
+              <string>2710e051eb1b12dba574f470834baa9e</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9929/48024/bugsplat-3.5.0.5-windows-509917.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9992/49191/bugsplat-3.5.0.5-windows-509980.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6878c5ac26ee1a7b8126d1c9f052e059</string>
+              <string>f2bb37c69f35522e49aae547d3408fd8</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9928/48018/bugsplat-3.5.0.5-windows64-509917.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9991/49185/bugsplat-3.5.0.5-windows64-509980.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 6805465023..e993979902 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -9,7 +9,7 @@ else (USESYSTEMLIBS)
   use_prebuilt_binary(bugsplat)
   if (WINDOWS)
     set(BUGSPLAT_LIBRARIES 
-      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat64.lib
+      ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
       )
   elseif (DARWIN)
 
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 7292f715b7..4e69597b61 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -449,9 +449,14 @@ class WindowsManifest(ViewerManifest):
             self.path("libhunspell.dll")
 
             # BugSplat
-            self.path("BsSndRpt64.exe")
-            self.path("BugSplat64.dll")
-            self.path("BugSplatRc64.dll")
+            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")
 
             # For google-perftools tcmalloc allocator.
             try:
@@ -580,11 +585,6 @@ class WindowsManifest(ViewerManifest):
             self.path("libvlccore.dll")
             self.path("plugins/")
 
-        with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst=""):
-            self.path("BsSndRpt64.exe")
-            self.path("BugSplat64.dll")
-            self.path("BugSplatRc64.dll")
-
         # pull in the crash logger and updater from other projects
         # tag:"crash-logger" here as a cue to the exporter
         self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
-- 
cgit v1.2.3


From 0ee774c39f3c689f998dae19d04af11981abd684 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Mon, 23 Oct 2017 11:37:06 -0700
Subject: Missed a place in the Copy3rdPartyLibs.cmake file (thank Windows
 Find) that needs to differentiate between 32 and 64 bit Windows builds

---
 indra/cmake/Copy3rdPartyLibs.cmake | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 9238d232b8..eaf1e31fce 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -39,11 +39,20 @@ if(WINDOWS)
         libeay32.dll
         glod.dll
         libhunspell.dll
-        BugSplat64.dll
-        BugSplatRc64.dll
-        BsSndRpt64.exe
         )
 
+    # Filenames are different for 32/64 bit BugSplat file and we don't
+    # have any control over them so need to branch.
+    if(ADDRESS_SIZE EQUAL 32)
+        set(release_files ${release_files} BugSplat.dll)
+        set(release_files ${release_files} BugSplatRc.dll)
+        set(release_files ${release_files} BsSndRpt.exe)
+    else(ADDRESS_SIZE EQUAL 32)
+        set(release_files ${release_files} BugSplat64.dll)
+        set(release_files ${release_files} BugSplatRc64.dll)
+        set(release_files ${release_files} BsSndRpt64.exe)
+    endif(ADDRESS_SIZE EQUAL 32)
+
     if (FMODEX)
 
         if(ADDRESS_SIZE EQUAL 32)
-- 
cgit v1.2.3


From d359dca06518d778c0f115afec8c759ca026de47 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Tue, 24 Oct 2017 14:28:43 -0700
Subject: painfully add in the path to the second life log file that we also
 send - painful because of string <--> wstring issues

---
 indra/llcommon/llapp.cpp | 26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index ea4a0fb59c..6ea1700ea8 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -406,27 +406,11 @@ bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2)
 	{
 		case MDSCB_EXCEPTIONCODE:
 		{
-			EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1;
-			DWORD code = p ? p->ExceptionCode : 0;
-
-			// create some files in the %temp% directory and attach them
-			wchar_t cmdString[2 * MAX_PATH];
-			wchar_t filePath[MAX_PATH];
-			wchar_t tempPath[MAX_PATH];
-			GetTempPathW(MAX_PATH, tempPath);
-
-			wsprintf(filePath, L"%sfile1.txt", tempPath);
-			wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath);
-			_wsystem(cmdString);
-			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
-
-			wsprintf(filePath, L"%sfile2.txt", tempPath);
-			wchar_t buf[_MAX_PATH];
-			gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH);
-
-			wsprintf(cmdString, L"echo Crash reporting is so clutch!  minidump path = %s > %s", buf, filePath);
-			_wsystem(cmdString);
-			gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath);
+			// 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;
 	}
-- 
cgit v1.2.3


From 2e3c5ac88a434ee437bc3e68b321d5bd0bcd7cc9 Mon Sep 17 00:00:00 2001
From: callum_linden <callum@lindenlab.com>
Date: Tue, 24 Oct 2017 16:13:23 -0700
Subject: Add in real SL viewer name and version

---
 indra/llcommon/CMakeLists.txt | 10 +++++++++-
 indra/llcommon/llapp.cpp      | 14 +++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 50e262ae7a..9c5481a977 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -14,6 +14,7 @@ include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
 include(BUGSPLAT)
+include(BuildVersion)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -255,7 +256,14 @@ set(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})
 
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6ea1700ea8..3e652dbdb5 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -431,9 +431,17 @@ void LLApp::setupErrorHandling(bool second_instance)
 #if BUGSPLAT_ENABLED
 	// TODOCP: populate these fields correctly
 	static const wchar_t *bugdb_name = L"second_life_callum_test";
-	static const wchar_t *app_name = L"SecondLifeViewer";
-	static const wchar_t *app_version = L"1.0.0";
-	gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL);
+
+	// 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
-- 
cgit v1.2.3


From 508e754eb4501b9c3fbfbfde52ca7ae8ed0f06b7 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 14 Dec 2017 18:12:22 -0500
Subject: fix tab character coding style violation

---
 indra/llcommon/CMakeLists.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 9c5481a977..c8e44d7ba4 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -257,13 +257,13 @@ set(llcommon_HEADER_FILES
 
 set_source_files_properties(${llcommon_HEADER_FILES}
                             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
-							)
+                            COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
+                            )
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
-- 
cgit v1.2.3


From 2fb39cb45f9ef502e9ea23df096fa5b3f2f806fa Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 10 May 2018 15:05:55 -0400
Subject: SL-821: Update to bugsplat build 515327

---
 autobuild.xml | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 75b19709bc..25bc8d8af9 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -239,14 +239,26 @@
         <string>bugsplat</string>
         <key>platforms</key>
         <map>
+          <key>darwin64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>9a14b64569c998fb7ef6e3bb690eda29</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17916/122458/bugsplat-1.0.2.515327-darwin64-515327.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>darwin64</string>
+          </map>
           <key>windows</key>
           <map>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2710e051eb1b12dba574f470834baa9e</string>
+              <string>90d85d1ac17f0049c8c48110e790a61f</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9992/49191/bugsplat-3.5.0.5-windows-509980.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17918/122472/bugsplat-3.5.0.5.515327-windows-515327.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -256,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f2bb37c69f35522e49aae547d3408fd8</string>
+              <string>9af7c080ebf0b961d7a4ccac7a303508</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/9991/49185/bugsplat-3.5.0.5-windows64-509980.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17917/122466/bugsplat-3.5.0.5.515327-windows64-515327.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>3.5.0.5</string>
+        <string>1.0.2.515327</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 3de5bab17459ed5bf0494d7bd2a531c473e20b7e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 11 May 2018 16:00:20 -0400
Subject: SL-821: Move BugSplat includes/libs from llcommon to newview.

No C++ source in llcommon references any of the BugSplat code.
---
 indra/llcommon/CMakeLists.txt | 3 ---
 indra/newview/CMakeLists.txt  | 3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index c8e44d7ba4..4eba1d5451 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,7 +13,6 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
-include(BUGSPLAT)
 include(BuildVersion)
 
 include_directories(
@@ -23,7 +22,6 @@ include_directories(
     ${ZLIB_INCLUDE_DIRS}
     ${BREAKPAD_INCLUDE_DIRECTORIES}
     ${URIPARSER_INCLUDE_DIRS}
-    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 # add_executable(lltreeiterators lltreeiterators.cpp)
@@ -301,7 +299,6 @@ target_link_libraries(
     ${BOOST_SYSTEM_LIBRARY}
     ${GOOGLE_PERFTOOLS_LIBRARIES}
     ${URIPARSER_LIBRARIES}
-    ${BUGSPLAT_LIBRARIES}
     )
 
 if (DARWIN)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6b16713add..1fd0af0558 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -4,6 +4,7 @@ project(viewer)
 
 include(00-Common)
 include(Boost)
+include(bugsplat)
 include(BuildPackagesInfo)
 include(BuildVersion)
 include(CMakeCopyIfDifferent)
@@ -91,6 +92,7 @@ include_directories(
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     ${LLAPPEARANCE_INCLUDE_DIRS}
     ${CMAKE_CURRENT_SOURCE_DIR}
+    ${BUGSPLAT_INCLUDE_DIR}
     )
 
 include_directories(SYSTEM
@@ -1976,6 +1978,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${LLAPPEARANCE_LIBRARIES}
+    ${BUGSPLAT_LIBRARIES}
     )
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
-- 
cgit v1.2.3


From 78b8a0c3e44d7ae0931da7ea6064a12bd3d77b8c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 11 May 2018 17:04:24 -0400
Subject: SL-821: Use one self.path() call for everything under "llplugin".

---
 indra/newview/viewer_manifest.py | 195 ++++++++++++++++++++-------------------
 1 file changed, 98 insertions(+), 97 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 437769726d..3375d4e071 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -605,103 +605,104 @@ class WindowsManifest(ViewerManifest):
         self.path("ca-bundle.crt")
 
         # Media plugins - CEF
-        with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_cef.dll")
-
-        # Media plugins - LibVLC
-        with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
-            self.path("media_plugin_libvlc.dll")
-
-        # Media plugins - Example (useful for debugging - not shipped with release viewer)
-        if self.channel_type() != 'release':
-            with self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
-                self.path("media_plugin_example.dll")
-
-        # CEF runtime files - debug
-        # CEF runtime files - not debug (release, relwithdebinfo etc.)
-        config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
-        with self.prefix(src=os.path.join(pkgdir, 'bin', config), dst="llplugin"):
-            self.path("chrome_elf.dll")
-            self.path("d3dcompiler_43.dll")
-            self.path("d3dcompiler_47.dll")
-            self.path("libcef.dll")
-            self.path("libEGL.dll")
-            self.path("libGLESv2.dll")
-            self.path("dullahan_host.exe")
-            self.path("natives_blob.bin")
-            self.path("snapshot_blob.bin")
-            self.path("widevinecdmadapter.dll")
-
-        # MSVC DLLs needed for CEF and have to be in same directory as plugin
-        with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
-            self.path("msvcp120.dll")
-            self.path("msvcr120.dll")
-
-        # CEF files common to all configurations
-        with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="llplugin"):
-            self.path("cef.pak")
-            self.path("cef_100_percent.pak")
-            self.path("cef_200_percent.pak")
-            self.path("cef_extensions.pak")
-            self.path("devtools_resources.pak")
-            self.path("icudtl.dat")
-
-        with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
-            self.path("am.pak")
-            self.path("ar.pak")
-            self.path("bg.pak")
-            self.path("bn.pak")
-            self.path("ca.pak")
-            self.path("cs.pak")
-            self.path("da.pak")
-            self.path("de.pak")
-            self.path("el.pak")
-            self.path("en-GB.pak")
-            self.path("en-US.pak")
-            self.path("es-419.pak")
-            self.path("es.pak")
-            self.path("et.pak")
-            self.path("fa.pak")
-            self.path("fi.pak")
-            self.path("fil.pak")
-            self.path("fr.pak")
-            self.path("gu.pak")
-            self.path("he.pak")
-            self.path("hi.pak")
-            self.path("hr.pak")
-            self.path("hu.pak")
-            self.path("id.pak")
-            self.path("it.pak")
-            self.path("ja.pak")
-            self.path("kn.pak")
-            self.path("ko.pak")
-            self.path("lt.pak")
-            self.path("lv.pak")
-            self.path("ml.pak")
-            self.path("mr.pak")
-            self.path("ms.pak")
-            self.path("nb.pak")
-            self.path("nl.pak")
-            self.path("pl.pak")
-            self.path("pt-BR.pak")
-            self.path("pt-PT.pak")
-            self.path("ro.pak")
-            self.path("ru.pak")
-            self.path("sk.pak")
-            self.path("sl.pak")
-            self.path("sr.pak")
-            self.path("sv.pak")
-            self.path("sw.pak")
-            self.path("ta.pak")
-            self.path("te.pak")
-            self.path("th.pak")
-            self.path("tr.pak")
-            self.path("uk.pak")
-            self.path("vi.pak")
-            self.path("zh-CN.pak")
-            self.path("zh-TW.pak")
-
-            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="llplugin"):
+        with self.prefix(dst="llplugin"):
+            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']):
+                self.path("media_plugin_cef.dll")
+
+            # Media plugins - LibVLC
+            with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration']):
+                self.path("media_plugin_libvlc.dll")
+
+            # Media plugins - Example (useful for debugging - not shipped with release viewer)
+            if self.channel_type() != 'release':
+                with self.prefix(src='../media_plugins/example/%s' % self.args['configuration']):
+                    self.path("media_plugin_example.dll")
+
+            # CEF runtime files - debug
+            # CEF runtime files - not debug (release, relwithdebinfo etc.)
+            config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
+            with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
+                self.path("chrome_elf.dll")
+                self.path("d3dcompiler_43.dll")
+                self.path("d3dcompiler_47.dll")
+                self.path("libcef.dll")
+                self.path("libEGL.dll")
+                self.path("libGLESv2.dll")
+                self.path("dullahan_host.exe")
+                self.path("natives_blob.bin")
+                self.path("snapshot_blob.bin")
+                self.path("widevinecdmadapter.dll")
+
+            # MSVC DLLs needed for CEF and have to be in same directory as plugin
+            with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release')):
+                self.path("msvcp120.dll")
+                self.path("msvcr120.dll")
+
+            # CEF files common to all configurations
+            with self.prefix(src=os.path.join(pkgdir, 'resources')):
+                self.path("cef.pak")
+                self.path("cef_100_percent.pak")
+                self.path("cef_200_percent.pak")
+                self.path("cef_extensions.pak")
+                self.path("devtools_resources.pak")
+                self.path("icudtl.dat")
+
+            with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+                self.path("am.pak")
+                self.path("ar.pak")
+                self.path("bg.pak")
+                self.path("bn.pak")
+                self.path("ca.pak")
+                self.path("cs.pak")
+                self.path("da.pak")
+                self.path("de.pak")
+                self.path("el.pak")
+                self.path("en-GB.pak")
+                self.path("en-US.pak")
+                self.path("es-419.pak")
+                self.path("es.pak")
+                self.path("et.pak")
+                self.path("fa.pak")
+                self.path("fi.pak")
+                self.path("fil.pak")
+                self.path("fr.pak")
+                self.path("gu.pak")
+                self.path("he.pak")
+                self.path("hi.pak")
+                self.path("hr.pak")
+                self.path("hu.pak")
+                self.path("id.pak")
+                self.path("it.pak")
+                self.path("ja.pak")
+                self.path("kn.pak")
+                self.path("ko.pak")
+                self.path("lt.pak")
+                self.path("lv.pak")
+                self.path("ml.pak")
+                self.path("mr.pak")
+                self.path("ms.pak")
+                self.path("nb.pak")
+                self.path("nl.pak")
+                self.path("pl.pak")
+                self.path("pt-BR.pak")
+                self.path("pt-PT.pak")
+                self.path("ro.pak")
+                self.path("ru.pak")
+                self.path("sk.pak")
+                self.path("sl.pak")
+                self.path("sr.pak")
+                self.path("sv.pak")
+                self.path("sw.pak")
+                self.path("ta.pak")
+                self.path("te.pak")
+                self.path("th.pak")
+                self.path("tr.pak")
+                self.path("uk.pak")
+                self.path("vi.pak")
+                self.path("zh-CN.pak")
+                self.path("zh-TW.pak")
+
+            with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
                 self.path("libvlc.dll")
                 self.path("libvlccore.dll")
                 self.path("plugins/")
-- 
cgit v1.2.3


From ed891c60de4169fa8ef4cc19e953e389cc4df60e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 05:33:14 -0400
Subject: SL-821: Add LL_TO_WSTRING() macro to llpreprocessor.h.

Also use existing LL_TO_STRING() macro to stringize LL_VIEWER_CHANNEL in
llversioninfo.cpp and its tests.
---
 indra/llcommon/llpreprocessor.h            | 2 ++
 indra/newview/llversioninfo.cpp            | 7 ++-----
 indra/newview/tests/llversioninfo_test.cpp | 6 ++----
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 2879038c36..ef015fdce4 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -198,6 +198,8 @@
 
 #define LL_TO_STRING_HELPER(x) #x
 #define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
+#define LL_TO_WSTRING_HELPER(x) L#x
+#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
 #define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
 #define LL_GLUE_IMPL(x, y) x##y
 #define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 375dce485d..4e07223784 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -101,14 +101,11 @@ namespace
 {
 	// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
 	// macro expands to the string name of the channel, but without quotes. We
-	// need to turn it into a quoted string. This macro trick does that.
-#define stringize_inner(x) #x
-#define stringize_outer(x) stringize_inner(x)
-
+	// need to turn it into a quoted string. LL_TO_STRING() does that.
 	/// Storage of the channel name the viewer is using.
 	//  The channel name is set by hardcoded constant, 
 	//  or by calling LLVersionInfo::resetChannel()
-	std::string sWorkingChannelName(stringize_outer(LL_VIEWER_CHANNEL));
+	std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL));
 
 	// Storage for the "version and channel" string.
 	// This will get reset too.
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 2f7a4e9601..58f0469552 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -33,10 +33,8 @@
 
 // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
 // macro expands to the string name of the channel, but without quotes. We
-// need to turn it into a quoted string. This macro trick does that.
-#define stringize_inner(x) #x
-#define stringize_outer(x) stringize_inner(x)
-#define ll_viewer_channel stringize_outer(LL_VIEWER_CHANNEL)
+// need to turn it into a quoted string. LL_TO_STRING() does that.
+#define ll_viewer_channel LL_TO_STRING(LL_VIEWER_CHANNEL)
 
 namespace tut
 {
-- 
cgit v1.2.3


From c09d9c12e79fde83a87b2394c88b32e568271eda Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 05:45:36 -0400
Subject: SL-821: Add WSTRINGIZE() and DEWSTRINGIZE() macros for wide strings.

Streamline convenience overload stringize(std::wstring); make convenience
overload wstringize(std::string) symmetrically convert from UTF-8 string.

Also eliminate STRINGIZE() et al. dependency on Boost.Phoenix: use lambdas
instead.

Using lambdas instead of template expansion necessitates reordering some code
in wrapllerrs.h.
---
 indra/llcommon/stringize.h        | 52 ++++++++++++++++++++++-----------------
 indra/llcommon/tests/wrapllerrs.h | 14 +++++------
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d7297..38dd198ad3 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,6 @@
 #define LL_STRINGIZE_H
 
 #include <sstream>
-#include <boost/phoenix/phoenix.hpp>
 #include <llstring.h>
 
 /**
@@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
  */
 inline std::string stringize(const std::wstring& item)
 {
-    LL_WARNS() << "WARNING:  Possible narrowing" << LL_ENDL;
-    
-    std::string s;
-    
-    s = wstring_to_utf8str(item);
-    return gstringize<char>(s);
+    return wstring_to_utf8str(item);
 }
 
 /**
@@ -76,7 +70,10 @@ std::string stringize(const T& item)
  */
 inline std::wstring wstringize(const std::string& item)
 {
-    return gstringize<wchar_t>(item.c_str());
+    // utf8str_to_wstring() returns LLWString, which isn't necessarily the
+    // same as std::wstring
+    LLWString s(utf8str_to_wstring(item));
+    return std::wstring(s.begin(), s.end());
 }
 
 /**
@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
 /**
  * stringize_f(functor)
  */
-template <typename Functor>
-std::string stringize_f(Functor const & f)
+template <typename CHARTYPE, typename Functor>
+std::basic_string<CHARTYPE> stringize_f(Functor const & f)
 {
-    std::ostringstream out;
+    std::basic_ostringstream<CHARTYPE> out;
     f(out);
     return out.str();
 }
@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
  * return out.str();
  * @endcode
  */
-#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
+#define STRINGIZE(EXPRESSION) (stringize_f<char>([&](std::ostream& out){ out << EXPRESSION; }))
 
+/**
+ * WSTRINGIZE() is the wstring equivalent of STRINGIZE()
+ */
+#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
 
 /**
  * destringize(str)
  * defined for symmetry with stringize
- * *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
+ * @NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
  * leading/trailing whitespace and handling of bad_lexical_cast exceptions
+ * @NOTE - no need for dewstringize(), since passing std::wstring will Do The
+ * Right Thing
  */
-template <typename T>
-T destringize(std::string const & str)
+template <typename T, typename CHARTYPE>
+T destringize(std::basic_string<CHARTYPE> const & str)
 {
-	T val;
-    std::istringstream in(str);
-	in >> val;
+    T val;
+    std::basic_istringstream<CHARTYPE> in(str);
+    in >> val;
     return val;
 }
 
 /**
  * destringize_f(str, functor)
  */
-template <typename Functor>
-void destringize_f(std::string const & str, Functor const & f)
+template <typename CHARTYPE, typename Functor>
+void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
 {
-    std::istringstream in(str);
+    std::basic_istringstream<CHARTYPE> in(str);
     f(in);
 }
 
@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
  * std::istringstream in(str);
  * in >> item1 >> item2 >> item3 ... ;
  * @endcode
+ * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
+ * more since DESTRINGIZE() should do the right thing with a std::wstring. But
+ * until then, the lambda we pass must accept the right std::basic_istream.
  */
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
-
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
+#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
 
 #endif /* ! defined(LL_STRINGIZE_H) */
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 9a4bbbd630..08fbf19b1c 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -109,6 +109,12 @@ public:
         mMessages.push_back(message);
     }
 
+    friend inline
+    std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
+    {
+        return log.streamto(out);
+    }
+
     /// Don't assume the message we want is necessarily the LAST log message
     /// emitted by the underlying code; search backwards through all messages
     /// for the sought string.
@@ -126,7 +132,7 @@ public:
 
         throw tut::failure(STRINGIZE("failed to find '" << search
                                      << "' in captured log messages:\n"
-                                     << boost::ref(*this)));
+                                     << *this));
     }
 
     std::ostream& streamto(std::ostream& out) const
@@ -200,10 +206,4 @@ private:
 	LLError::RecorderPtr mRecorder;
 };
 
-inline
-std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
-{
-    return log.streamto(out);
-}
-
 #endif /* ! defined(LL_WRAPLLERRS_H) */
-- 
cgit v1.2.3


From c5f618d096f05bdff91a5d384c46e26840f5a771 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 06:53:42 -0400
Subject: 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.
---
 indra/cmake/CMakeLists.txt         |  1 +
 indra/cmake/bugsplat.cmake         | 46 +++++++++++++++++------------
 indra/llcommon/CMakeLists.txt      | 10 +------
 indra/llcommon/llapp.cpp           | 60 ++------------------------------------
 indra/llcommon/llapp.h             | 10 +------
 indra/newview/CMakeLists.txt       | 23 ++++++++++++++-
 indra/newview/llappviewerwin32.cpp | 49 ++++++++++++++++++++++++++++---
 7 files changed, 101 insertions(+), 98 deletions(-)

diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 4a3ebe4835..84e1c5d6fd 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
     Audio.cmake
     BerkeleyDB.cmake
     Boost.cmake
+    bugsplat.cmake
     BuildVersion.cmake
     CEFPlugin.cmake
     CEFPlugin.cmake
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index e993979902..a7f4194905 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,20 +1,30 @@
-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)
-set(BUGSPLAT_FIND_REQUIRED ON)
+if (BUGSPLAT)
+  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)
-  include(FindBUGSPLAT)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(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)
+    endif (WINDOWS)
+    set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
+  endif (USESYSTEMLIBS)
+endif (BUGSPLAT)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 4eba1d5451..d9eb13d65a 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -13,7 +13,6 @@ include(GoogleBreakpad)
 include(Copy3rdPartyLibs)
 include(ZLIB)
 include(URIPARSER)
-include(BuildVersion)
 
 include_directories(
     ${EXPAT_INCLUDE_DIRS}
@@ -254,14 +253,7 @@ set(llcommon_HEADER_FILES
     )
 
 set_source_files_properties(${llcommon_HEADER_FILES}
-                            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
-                            )
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
 
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 3e652dbdb5..6cc9e804d4 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -49,20 +49,6 @@
 #include "google_breakpad/exception_handler.h"
 #include "stringize.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
@@ -399,26 +385,6 @@ void EnableCrashingOnCrashes()
 }
 #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)
 {
 	// 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)
 #if LL_WINDOWS
 
 #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();
 
 	// This sets a callback to handle w32 signals to the console window.
@@ -507,9 +454,8 @@ void LLApp::setupErrorHandling(bool second_instance)
 			mExceptionHandler->set_handle_debug_exceptions(true);
 		}
 	}
-#endif  // BUGSPLAT_ENABLED
-#endif	// LL_SEND_CRASH_REPORTS
-#else	// not LL_WINDOWS
+#endif
+#else
 	//
 	// Start up signal handling.
 	//
@@ -570,7 +516,7 @@ void LLApp::setupErrorHandling(bool second_instance)
 	}
 #endif
 
-#endif // LL_WINDOWS
+#endif
 	startErrorThread();
 }
 
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 5a4b7f13df..acd829d864 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -30,7 +30,6 @@
 #include <map>
 #include "llrun.h"
 #include "llsd.h"
-
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -40,14 +39,6 @@ class LLLiveFile;
 #include <signal.h>
 #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)();
 
 #if !LL_WINDOWS
@@ -325,6 +316,7 @@ private:
 	
 	google_breakpad::ExceptionHandler * mExceptionHandler;
 
+
 #if !LL_WINDOWS
 	friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 #endif
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1fd0af0558..2592b532c4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1354,6 +1354,11 @@ if (DARWIN)
 
   # This should be compiled with the viewer.
   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(APPKIT_LIBRARY AppKit)
@@ -1366,6 +1371,7 @@ if (DARWIN)
     ${AGL_LIBRARY}
     ${IOKIT_LIBRARY}
     ${COREAUDIO_LIBRARY}
+    ${BUGSPLAT_LIBRARIES}
     )
 
   # Add resource files to the project.
@@ -1393,6 +1399,11 @@ endif (DARWIN)
 
 if (LINUX)
     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)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
@@ -1409,6 +1420,11 @@ if (WINDOWS)
          llappviewerwin32.cpp
          llwindebug.cpp
          )
+    set_source_files_properties(
+      llappviewerwin32.cpp
+      PROPERTIES
+      COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+      )
 
     list(APPEND viewer_HEADER_FILES
          llappviewerwin32.h
@@ -1692,6 +1708,11 @@ if (SDL_FOUND)
     )
 endif (SDL_FOUND)
 
+if (BUGSPLAT)
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (BUGSPLAT)
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1790,7 +1811,7 @@ if (WINDOWS)
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
           )
     endif (FMODEX)
-    
+
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
       COMMAND ${PYTHON_EXECUTABLE}
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 48b3a1c485..8a014c55d7 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -66,8 +66,18 @@
 #endif
 
 #include "stringize.h"
+#include "lldir.h"
 
 #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
 {
     void (*gOldTerminateHandler)() = NULL;
@@ -495,15 +505,46 @@ bool LLAppViewerWin32::init()
 	LLWinDebug::instance();
 #endif
 
-#if LL_WINDOWS
 #if LL_SEND_CRASH_REPORTS
-
+#if ! defined(LL_BUGSPLAT)
 
 	LLAppViewer* pApp = LLAppViewer::instance();
 	pApp->initCrashReporting();
 
-#endif
-#endif
+#else // LL_BUGSPLAT
+
+	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();
 
-- 
cgit v1.2.3


From cd21556aef547dbb031e363d3a9b9f1893be4d08 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 10:58:59 -0400
Subject: SL-821: Convert wstrings to strings of __wchar_t for BugSplat API.

---
 indra/newview/llappviewerwin32.cpp | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 8a014c55d7..91c6f08000 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -76,7 +76,14 @@
 
 // FIXME: need a production BugSplat database name
 static const wchar_t *bugdb_name = L"second_life_callum_test";
-#endif
+
+// MiniDmpSender's constructor is defined to accept __wchar_t* instead of
+// plain wchar_t*.
+inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+{
+    return { str.begin(), str.end() };
+}
+#endif // LL_BUGSPLAT
 
 namespace
 {
@@ -518,8 +525,12 @@ bool LLAppViewerWin32::init()
 										   LL_VIEWER_VERSION_PATCH << '.' <<
 										   LL_VIEWER_VERSION_BUILD));
 
+	// have to convert normal wide strings to strings of __wchar_t
 	auto sender = new MiniDmpSender(
-		bugdb_name, LL_TO_WSTRING(LL_VIEWER_CHANNEL), version_string.c_str(), nullptr);
+		wunder(bugdb_name).c_str(),
+		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
+		wunder(version_string).c_str(),
+		nullptr);
 	sender->setCallback(
 		[sender](unsigned int nCode, void* lpVal1, void* lpVal2)
 		{
@@ -532,16 +543,17 @@ bool LLAppViewerWin32::init()
 			if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp)
 			{
 				// send the main viewer log file
-				// widen to wstring, then pass c_str()
+				// widen to wstring, convert to __wchar_t, then pass c_str()
 				sender->sendAdditionalFile(
-					wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str());
+					wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
 			}
 
 			return false;
 		});
 
+	// engage stringize() overload that converts from wstring
 	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-			   << version_string << ')' << LL_ENDL;
+			   << stringize(version_string) << ')' << LL_ENDL;
 
 #endif // LL_BUGSPLAT
 #endif // LL_SEND_CRASH_REPORTS
-- 
cgit v1.2.3


From 800b47ec230d1d2a6781dce5ba9816d10a37e91e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 17 May 2018 15:02:26 -0400
Subject: SL-821: Use classic-C BugSplat callback and static dumb pointer.

BugSplat has no business introducing a new C++ API based on classic-C function
pointers without even a generic pass-through user data pointer!
---
 indra/newview/llappviewerwin32.cpp | 65 ++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 27 deletions(-)

diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 91c6f08000..5f3bf14bc2 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -74,14 +74,43 @@
 #ifdef LL_BUGSPLAT
 #include "BugSplat.h"
 
-// FIXME: need a production BugSplat database name
-static const wchar_t *bugdb_name = L"second_life_callum_test";
-
-// MiniDmpSender's constructor is defined to accept __wchar_t* instead of
-// plain wchar_t*.
-inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+namespace
 {
-    return { str.begin(), str.end() };
+    // FIXME: need a production BugSplat database name
+    static const wchar_t *bugdb_name = L"second_life_callum_test";
+
+    // MiniDmpSender's constructor is defined to accept __wchar_t* instead of
+    // plain wchar_t*.
+    inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
+    {
+        return { str.begin(), str.end() };
+    }
+
+    // Irritatingly, MiniDmpSender::setCallback() is defined to accept a
+    // classic-C function pointer instead of an arbitrary C++ callable. In the
+    // latter case, we could pass a lambda that binds our MiniDmpSender
+    // pointer. As things stand, we must define an actual function and store
+    // the pointer statically.
+    static MiniDmpSender *sBugSplatSender = nullptr;
+
+    bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID 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, convert to __wchar_t, then pass c_str()
+            sBugSplatSender->sendAdditionalFile(
+                wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
+        }
+
+        return false;
+    }
 }
 #endif // LL_BUGSPLAT
 
@@ -526,30 +555,12 @@ bool LLAppViewerWin32::init()
 										   LL_VIEWER_VERSION_BUILD));
 
 	// have to convert normal wide strings to strings of __wchar_t
-	auto sender = new MiniDmpSender(
+	sBugSplatSender = new MiniDmpSender(
 		wunder(bugdb_name).c_str(),
 		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(),
 		wunder(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, convert to __wchar_t, then pass c_str()
-				sender->sendAdditionalFile(
-					wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str());
-			}
-
-			return false;
-		});
+	sBugSplatSender->setCallback(bugsplatSendLog);
 
 	// engage stringize() overload that converts from wstring
 	LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
-- 
cgit v1.2.3


From 4562773abcfe14425478889e2fea02da205013e1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:03:43 -0400
Subject: SL-821: Reorder CMakeLists.txt includes to resolve interdependencies.

---
 indra/newview/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2592b532c4..d28791485c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,6 +3,10 @@
 project(viewer)
 
 include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
 include(Boost)
 include(bugsplat)
 include(BuildPackagesInfo)
@@ -38,7 +42,6 @@ include(LLUI)
 include(LLVFS)
 include(LLWindow)
 include(LLXML)
-include(Linking)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
-- 
cgit v1.2.3


From 881bdec4b356ede32b0d0896334f7d6addac6c54 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:07:44 -0400
Subject: SL-821: Introduce macOS BugSplat initialization.

---
 indra/newview/llappdelegate-objc.mm | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index aebae4c434..2fa8319260 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -25,6 +25,9 @@
  */
 
 #import "llappdelegate-objc.h"
+#if defined(LL_BUGSPLAT)
+#import BugsplatMac;
+#endif
 #include "llwindowmacosx-objc.h"
 #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
 
@@ -64,6 +67,11 @@
 	[[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] start];
+#endif
 }
 
 - (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
-- 
cgit v1.2.3


From 3a885e9cb7bb86e82036b217e2aaf2d96106be43 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:29:16 -0400
Subject: SL-821: Use @import, not #import.

---
 indra/newview/llappdelegate-objc.mm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 2fa8319260..e8b4272e51 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -26,7 +26,7 @@
 
 #import "llappdelegate-objc.h"
 #if defined(LL_BUGSPLAT)
-#import BugsplatMac;
+@import BugsplatMac;
 #endif
 #include "llwindowmacosx-objc.h"
 #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
-- 
cgit v1.2.3


From 6f878571ec65d15f9e06af39375cc0251e4d1e2d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 13:54:39 -0400
Subject: SL-821: Add -fmodules to llappdelegate-objc.mm compile switches.

The BugsplatMac package is built as a module requiring @import. Using @import
requires Objective-C++ module support, which requires the -fmodules switch.
---
 indra/newview/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d28791485c..3501fdf800 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,6 +1361,7 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    COMPILE_FLAGS "-fmodules"
     )
 
   find_library(AGL_LIBRARY AGL)
-- 
cgit v1.2.3


From 170d5201ff97b4110fa9cc2a9a80234de53e12d8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 14:13:11 -0400
Subject: SL-821: Need -fcxx-modules for C++ module support, vs. classic C.

---
 indra/newview/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3501fdf800..7638a74bc1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,7 +1361,7 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
-    COMPILE_FLAGS "-fmodules"
+    COMPILE_FLAGS "-fmodules -fcxx-modules"
     )
 
   find_library(AGL_LIBRARY AGL)
-- 
cgit v1.2.3


From 670943de5a3bf4e7053c3afea0fda722e958f136 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 May 2018 15:02:17 -0400
Subject: SL-804, SL-824: Update to bugsplat build 515598

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 25bc8d8af9..fea35ac731 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9a14b64569c998fb7ef6e3bb690eda29</string>
+              <string>84ef190d0bc6cd3b535d8c625f324ba6</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17916/122458/bugsplat-1.0.2.515327-darwin64-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18354/126844/bugsplat-1.0.2.515598-darwin64-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>90d85d1ac17f0049c8c48110e790a61f</string>
+              <string>12625f3b3da813f10ec5b8e7eb84fe2d</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17918/122472/bugsplat-3.5.0.5.515327-windows-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18356/126857/bugsplat-3.5.0.5.515598-windows-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9af7c080ebf0b961d7a4ccac7a303508</string>
+              <string>0f88af634e5da368334ad6da7014b2ce</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/17917/122466/bugsplat-3.5.0.5.515327-windows64-515327.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18355/126855/bugsplat-3.5.0.5.515598-windows64-515598.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515327</string>
+        <string>1.0.2.515598</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 199c688e211125ae1b404425d9a8bd3bc036ea50 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 22 May 2018 11:52:00 -0400
Subject: SL-821: Copy BugsplatMac.framework into target application bundle.

---
 indra/newview/viewer_manifest.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 3375d4e071..d1a56c2230 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1005,13 +1005,15 @@ open "%s" --args "$@"
                         os.path.basename(Info_plist),
                         "Info.plist")
 
-                    # CEF framework goes inside viewer_app/Contents/Frameworks.
-                    # Remember where we parked this car.
                     with self.prefix(src="", dst="Frameworks"):
+                        # CEF framework goes inside viewer_app/Contents/Frameworks.
                         CEF_framework = "Chromium Embedded Framework.framework"
                         self.path2basename(relpkgdir, CEF_framework)
+                        # Remember where we parked this car.
                         CEF_framework = self.dst_path_of(CEF_framework)
 
+                        self.path2basename(relpkgdir, "BugsplatMac.framework")
+
                     with self.prefix(dst="MacOS"):
                         # CMake constructs the Second Life executable in the
                         # MacOS directory belonging to the top-level Second
-- 
cgit v1.2.3


From 48534c1badcd2f63dee2ee0106a109b93604827c Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 22 May 2018 12:00:20 -0400
Subject: SL-821: Add macOS rpath to Mac viewer executable for BugsplatMac.

The BugsplatMac framework is stamped with @rpath/BugsplatMac.framework/etc.,
so that's the dependency stamped into our viewer executable. To support that
lookup, direct CMake to add an appropriate RPATH to the executable.
---
 indra/newview/CMakeLists.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 7638a74bc1..954d5ce9ed 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1361,9 +1361,16 @@ if (DARWIN)
     llappdelegate-objc.mm
     PROPERTIES
     COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+    # BugsplatMac is a module, imported with @import. That language feature
+    # demands these switches.
     COMPILE_FLAGS "-fmodules -fcxx-modules"
     )
 
+  # from https://stackoverflow.com/a/43551534
+  set(CMAKE_MACOSX_RPATH 1)
+  # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+  set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks")
+
   find_library(AGL_LIBRARY AGL)
   find_library(APPKIT_LIBRARY AppKit)
   find_library(COCOA_LIBRARY Cocoa)
-- 
cgit v1.2.3


From 96dfab228ebce44287f66255ceb041e7f9d929b1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 04:54:09 -0400
Subject: SL-824: Update to bugsplat build 515654

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index fea35ac731..a3f5a83856 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>84ef190d0bc6cd3b535d8c625f324ba6</string>
+              <string>a834c6f8bafd4cb8e4a744510211237a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18354/126844/bugsplat-1.0.2.515598-darwin64-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18458/127802/bugsplat-1.0.2.515654-darwin64-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>12625f3b3da813f10ec5b8e7eb84fe2d</string>
+              <string>b8e47c5a20394e1add436e92fee9e356</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18356/126857/bugsplat-3.5.0.5.515598-windows-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18461/127812/bugsplat-3.5.0.5.515654-windows-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>0f88af634e5da368334ad6da7014b2ce</string>
+              <string>2f026674ed4ff8db34674af3cbd2072a</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18355/126855/bugsplat-3.5.0.5.515598-windows64-515598.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18462/127815/bugsplat-3.5.0.5.515654-windows64-515654.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515598</string>
+        <string>1.0.2.515654</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3


From 78dbccf14a7b2a454c3def823087955e0f7ac767 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 23 May 2018 06:42:23 -0400
Subject: SL-824: Update to bugsplat build 515657

---
 autobuild.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index a3f5a83856..e9ad39b921 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>a834c6f8bafd4cb8e4a744510211237a</string>
+              <string>c1f7431195bd5cb3cba724abdcc50104</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18458/127802/bugsplat-1.0.2.515654-darwin64-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18470/127908/bugsplat-1.0.2.515657-darwin64-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -256,9 +256,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b8e47c5a20394e1add436e92fee9e356</string>
+              <string>57832de6e3ba7eef7ac5f4e947277723</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18461/127812/bugsplat-3.5.0.5.515654-windows-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18472/127922/bugsplat-3.5.0.5.515657-windows-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -268,16 +268,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2f026674ed4ff8db34674af3cbd2072a</string>
+              <string>2ccc3aec7861e79e32e31e12807127b1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18462/127815/bugsplat-3.5.0.5.515654-windows64-515654.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/18471/127916/bugsplat-3.5.0.5.515657-windows64-515657.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.2.515654</string>
+        <string>1.0.2.515657</string>
       </map>
       <key>chardet</key>
       <map>
-- 
cgit v1.2.3