diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f518704e06a829e084a211b0b73c9cfdd821e0f2..a1d73acfa5fd42096e9560176a16f4daffbc0b5b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5549,6 +5549,33 @@ void LLAppViewer::forceErrorDriverCrash()
 	glDeleteTextures(1, NULL);
 }
 
+void LLAppViewer::forceErrorCoroutineCrash()
+{
+    LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
+    LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw std::exception("A deliberate crash from LLCoros"); });
+}
+
+void LLAppViewer::forceErrorThreadCrash()
+{
+    class LLCrashTestThread : public LLThread
+    {
+    public:
+
+        LLCrashTestThread() : LLThread("Crash logging test thread")
+        {
+        }
+
+        void run()
+        {
+            LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL;
+        }
+    };
+
+    LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL;
+    LLCrashTestThread *thread = new LLCrashTestThread();
+    thread->start();
+}
+
 void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
 {
 	if(!mMainloopTimeout)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 5332fe2deba5111e2a71cdcd248865b0cb5472e2..6db45583eb7b8c604359c0cfd9348156c1794380 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -150,6 +150,8 @@ class LLAppViewer : public LLApp
     virtual void forceErrorInfiniteLoop();
     virtual void forceErrorSoftwareException();
     virtual void forceErrorDriverCrash();
+    virtual void forceErrorCoroutineCrash();
+    virtual void forceErrorThreadCrash();
 
 	// The list is found in app_settings/settings_files.xml
 	// but since they are used explicitly in code,
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 9b1c0d1f8b01d7200973daefaae86e76565eee9c..bb6156e209cd5809ed3adc67e5f951e257fe14d9 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -609,6 +609,13 @@ bool LLAppViewerWin32::init()
 #else // LL_BUGSPLAT
 #pragma message("Building with BugSplat")
 
+    if (!isSecondInstance())
+    {
+        // Cleanup previous session
+        std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+        LLFile::remove(log_file, ENOENT);
+    }
+
 	std::string build_data_fname(
 		gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
 	// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE
@@ -616,7 +623,7 @@ bool LLAppViewerWin32::init()
 	llifstream inf(build_data_fname.c_str());
 	if (! inf.is_open())
 	{
-		LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
+		LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname
 				   << "'" << LL_ENDL;
 	}
 	else
@@ -626,7 +633,7 @@ bool LLAppViewerWin32::init()
 		if (! reader.parse(inf, build_data, false)) // don't collect comments
 		{
 			// gah, the typo is baked into Json::Reader API
-			LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
+			LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
 					   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;
 		}
 		else
@@ -634,7 +641,7 @@ bool LLAppViewerWin32::init()
 			Json::Value BugSplat_DB = build_data["BugSplat DB"];
 			if (! BugSplat_DB)
 			{
-				LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
+				LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
 						   << build_data_fname << "'" << LL_ENDL;
 			}
 			else
@@ -645,18 +652,35 @@ bool LLAppViewerWin32::init()
 													   LL_VIEWER_VERSION_PATCH << '.' <<
 													   LL_VIEWER_VERSION_BUILD));
 
+                DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
+                                MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
+
+                bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
+                if (needs_log_file)
+                {
+                    // Startup only!
+                    LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
+                    dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
+                }
+
 				// have to convert normal wide strings to strings of __wchar_t
 				sBugSplatSender = new MiniDmpSender(
 					WCSTR(BugSplat_DB.asString()),
 					WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
 					WCSTR(version_string),
 					nullptr,              // szAppIdentifier -- set later
-					MDSF_NONINTERACTIVE | // automatically submit report without prompting
-					MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
+					dwFlags);
 				sBugSplatSender->setCallback(bugsplatSendLog);
 
+                if (needs_log_file)
+                {
+                    // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
+                    std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+                    sBugSplatSender->setLogFilePath(WCSTR(log_file));
+                }
+
 				// engage stringize() overload that converts from wstring
-				LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+				LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
 						   << ' ' << stringize(version_string) << ')' << LL_ENDL;
 			} // got BugSplat_DB
 		} // parsed build_data.json
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 29888fe9fdbf1b6f472fcde6d33f022146533426..2299f710f2273344c1715ecdc3d15dedacb84f8c 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -286,6 +286,8 @@ void force_error_bad_memory_access(void *);
 void force_error_infinite_loop(void *);
 void force_error_software_exception(void *);
 void force_error_driver_crash(void *);
+void force_error_coroutine_crash(void *);
+void force_error_thread_crash(void *);
 
 void handle_force_delete(void*);
 void print_object_info(void*);
@@ -2363,6 +2365,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
 	}
 };
 
+class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
+{
+    bool handleEvent(const LLSD& userdata)
+    {
+        force_error_coroutine_crash(NULL);
+        return true;
+    }
+};
+
+class LLAdvancedForceErrorThreadCrash : public view_listener_t
+{
+    bool handleEvent(const LLSD& userdata)
+    {
+        force_error_thread_crash(NULL);
+        return true;
+    }
+};
+
 class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8035,6 +8055,16 @@ void force_error_driver_crash(void *)
     LLAppViewer::instance()->forceErrorDriverCrash();
 }
 
+void force_error_coroutine_crash(void *)
+{
+    LLAppViewer::instance()->forceErrorCoroutineCrash();
+}
+
+void force_error_thread_crash(void *)
+{
+    LLAppViewer::instance()->forceErrorThreadCrash();
+}
+
 class LLToolsUseSelectionForGrid : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -9202,6 +9232,8 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
 	view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
 	view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
+    view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
+    view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
 	view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
 
 	// Advanced (toplevel)
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 5fa1847d1b840941e54557745c34542d3056f5fb..3ce55be5548c95068ce0a188a1a9ce159d03f5e3 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2437,6 +2437,18 @@ function="World.EnvPreset"
                 <menu_item_call.on_click
                  function="Advanced.ForceErrorSoftwareException" />
             </menu_item_call>
+            <menu_item_call
+             label="Force a Crash in a Coroutine"
+             name="Force a Crash in a Coroutine">
+                <menu_item_call.on_click
+                 function="Advanced.ForceErrorCoroutineCrash" />
+            </menu_item_call>
+            <menu_item_call
+             label="Force a Crash in a Thread"
+             name="Force a Crash in a Thread">
+                <menu_item_call.on_click
+                 function="Advanced.ForceErrorThreadCrash" />
+            </menu_item_call>
             <menu_item_call
              label="Force Disconnect Viewer"
              name="Force Disconnect Viewer">