From 719edddf0498752a0295502d62710823d1a72cc7 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Fri, 21 May 2010 09:38:29 -0700
Subject: Switch Darwin to use breakpad minidump rather than os generated crash
 stack.

---
 indra/llcommon/CMakeLists.txt |  1 +
 indra/llcommon/llapp.cpp      | 51 ++++++++++++++++++++++++++++++++++++++++++-
 indra/llcommon/llapp.h        | 11 ++++++++--
 3 files changed, 60 insertions(+), 3 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 3c689930b8..051e198e75 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -259,6 +259,7 @@ endif(LLCOMMON_LINK_SHARED)
 
 target_link_libraries(
     llcommon
+    exception_handler
     ${APRUTIL_LIBRARIES}
     ${APR_LIBRARIES}
     ${EXPAT_LIBRARIES}
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6b2d1b7c20..e766563c6f 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -56,6 +56,11 @@ BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
 # include <unistd.h> // for fork()
 void setup_signals();
 void default_unix_signal_handler(int signum, siginfo_t *info, void *);
+
+// Called by breakpad exception handler after the minidump has been generated.
+bool darwin_post_minidump_callback(const char *dump_dir,
+					  const char *minidump_id,
+					  void *context, bool succeeded);
 # if LL_DARWIN
 /* OSX doesn't support SIGRT* */
 S32 LL_SMACKDOWN_SIGNAL = SIGUSR1;
@@ -123,7 +128,10 @@ void LLApp::commonCtor()
 
 	// Set the application to this instance.
 	sApplication = this;
-
+	
+	mExceptionHandler = 0;
+	
+	memset(minidump_path, 0, MAX_MINDUMP_PATH_LENGTH);
 }
 
 LLApp::LLApp(LLErrorThread *error_thread) :
@@ -152,6 +160,8 @@ LLApp::~LLApp()
 		delete mThreadErrorp;
 		mThreadErrorp = NULL;
 	}
+	
+	if(mExceptionHandler != 0) delete mExceptionHandler;
 
 	LLCommon::cleanupClass();
 }
@@ -285,6 +295,15 @@ void LLApp::setupErrorHandling()
 
 	setup_signals();
 
+	
+#ifdef LL_DARWIN
+	// Add google breakpad exception handler configured for Darwin.
+	if(mExceptionHandler == 0)
+	{
+		std::string dumpPath = "/tmp/";
+		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &darwin_post_minidump_callback, 0, true);
+	}
+#endif
 #endif
 
 	startErrorThread();
@@ -587,6 +606,7 @@ void setup_signals()
 
 	// Asynchronous signals that result in core
 	sigaction(SIGQUIT, &act, NULL);
+	
 }
 
 void clear_signals()
@@ -766,3 +786,32 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
 }
 
 #endif // !WINDOWS
+
+bool darwin_post_minidump_callback(const char *dump_dir,
+					  const char *minidump_id,
+					  void *context, bool succeeded)
+{
+	// Copy minidump file path into fixed buffer in the app instance to avoid
+	// heap allocations in a crash handler.
+	
+	// path format: <dump_dir>/<minidump_id>.dmp
+	int dirPathLength = strlen(dump_dir);
+	int idLength = strlen(minidump_id);
+	
+	// The path must not be truncated.
+	llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
+	
+	char * path = LLApp::instance()->minidump_path;
+	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
+	strncpy(path, dump_dir, remaining);
+	remaining -= dirPathLength;
+	path += dirPathLength;
+	strncpy(path, minidump_id, remaining);
+	remaining -= idLength;
+	path += idLength;
+	strncpy(path, ".dmp", remaining);
+	
+	llinfos << "generated minidump: " << LLApp::instance()->minidump_path << llendl;
+	LLApp::runErrorHandler();
+	return true;
+}
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index e5b8edf9c3..cd17532203 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,6 +38,8 @@
 #include "llsd.h"
 #include "lloptioninterface.h"
 
+#include "exception_handler.h"
+
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -228,6 +230,8 @@ public:
 
 	void setErrorHandler(LLAppErrorHandler handler);
 	void setSyncErrorHandler(LLAppErrorHandler handler);
+	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
+	static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread.
 	//@}
 
 #if !LL_WINDOWS
@@ -265,6 +269,9 @@ public:
 	typedef std::map<std::string, std::string> string_map;
 	string_map mOptionMap;	// Contains all command-line options and arguments in a map
 
+	// Contains the path to minidump file after a crash.
+	static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
+	char minidump_path[MAX_MINDUMP_PATH_LENGTH];
 protected:
 
 	static void setStatus(EAppStatus status);		// Use this to change the application status.
@@ -286,8 +293,6 @@ protected:
 private:
 	void startErrorThread();
 	
-	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
-	static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread.
 
 	// *NOTE: On Windows, we need a routine to reset the structured
 	// exception handler when some evil driver has taken it over for
@@ -315,6 +320,8 @@ private:
 private:
 	// the static application instance if it was created.
 	static LLApp* sApplication;
+	
+	google_breakpad::ExceptionHandler * mExceptionHandler;
 
 
 #if !LL_WINDOWS
-- 
cgit v1.2.3


From fa06293a4c637b31094a8c6907982851d4d0b464 Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Fri, 21 May 2010 11:48:07 -0700
Subject: Added call to use_prebuilt_binary for google-breakpad so it actually
 gets installed by install.py.

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

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 051e198e75..2fcb04321c 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -9,6 +9,7 @@ include(Linking)
 include(Boost)
 include(Pth)
 include(LLSharedLibs)
+include(GoogleBreakpad)
 include(GooglePerfTools)
 include(Copy3rdPartyLibs)
 
@@ -259,7 +260,7 @@ endif(LLCOMMON_LINK_SHARED)
 
 target_link_libraries(
     llcommon
-    exception_handler
+    ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
     ${APRUTIL_LIBRARIES}
     ${APR_LIBRARIES}
     ${EXPAT_LIBRARIES}
-- 
cgit v1.2.3


From ba809777e5ba240622f6c67ff400733899c275bf Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Fri, 21 May 2010 14:39:55 -0700
Subject: New google breakpad package for windows with winsock2 fix, and DLL
 CRT library usage. Also moved headers into libraries/include/google_breakpad.
 Mac and linux packages to come shortly.

---
 indra/llcommon/llapp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index cd17532203..348eec0c48 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,7 +38,7 @@
 #include "llsd.h"
 #include "lloptioninterface.h"
 
-#include "exception_handler.h"
+#include "google_breakpad/exception_handler.h"
 
 // Forward declarations
 template <typename Type> class LLAtomic32;
-- 
cgit v1.2.3


From 1077ab49c171c0f310f9b76b360ea2ad162a31ff Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 24 May 2010 15:19:33 -0700
Subject: Just enough hackery to get minidumps into Wind'ohs crash reports. 
 Code clean up needed.

---
 indra/llcommon/llapp.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 indra/llcommon/llapp.h   |  6 +++--
 2 files changed, 71 insertions(+), 2 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index e766563c6f..e22ff869e7 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -30,6 +30,8 @@
  * $/LicenseInfo$
  */
 
+#include <cstdlib>
+
 #include "linden_common.h"
 #include "llapp.h"
 
@@ -43,6 +45,8 @@
 #include "llstl.h" // for DeletePointer()
 #include "lleventtimer.h"
 
+#include "google_breakpad/exception_handler.h"
+
 //
 // Signal handling
 //
@@ -51,6 +55,12 @@
 #if LL_WINDOWS
 LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);
 BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
+bool windows_post_minidump_callback(const wchar_t* dump_path,
+									const wchar_t* minidump_id,
+									void* context,
+									EXCEPTION_POINTERS* exinfo,
+									MDRawAssertionInfo* assertion,
+									bool succeeded);
 #else
 # include <signal.h>
 # include <unistd.h> // for fork()
@@ -285,6 +295,13 @@ void LLApp::setupErrorHandling()
 	// The viewer shouldn't be affected, sicne its a windowed app.
 	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE);
 
+	if(mExceptionHandler == 0)
+	{
+		llwarns << "adding breakpad exception handler" << llendl;
+		mExceptionHandler = new google_breakpad::ExceptionHandler(
+			L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);
+	}
+
 #else
 	//
 	// Start up signal handling.
@@ -815,3 +832,53 @@ bool darwin_post_minidump_callback(const char *dump_dir,
 	LLApp::runErrorHandler();
 	return true;
 }
+
+bool windows_post_minidump_callback(const wchar_t* dump_path,
+									const wchar_t* minidump_id,
+									void* context,
+									EXCEPTION_POINTERS* exinfo,
+									MDRawAssertionInfo* assertion,
+									bool succeeded)
+{
+	char * path = LLApp::instance()->minidump_path;
+	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
+	size_t bytesUsed;
+
+	bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining));
+	remaining -= bytesUsed;
+	path += bytesUsed;
+	if(remaining > 0)
+	{
+		bytesUsed = wcstombs(path, minidump_id, static_cast<size_t>(remaining));
+		remaining -= bytesUsed;
+		path += bytesUsed;
+	}
+	if(remaining > 0)
+	{
+		strncpy(path, ".dmp", remaining);
+	}
+
+	llinfos << "generated minidump: " << LLApp::instance()->minidump_path << llendl;
+    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
+	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
+    // *TODO: Translate the signals/exceptions into cross-platform stuff
+	// Windows implementation
+	llinfos << "Entering Windows Exception Handler..." << llendl;
+
+	if (LLApp::isError())
+	{
+		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl;
+	}
+
+	// Flag status to error, so thread_error starts its work
+	LLApp::setError();
+
+	// Block in the exception handler until the app has stopped
+	// This is pretty sketchy, but appears to work just fine
+	while (!LLApp::isStopped())
+	{
+		ms_sleep(10);
+	}
+
+	return true;
+}
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 348eec0c48..725c13866f 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,8 +38,6 @@
 #include "llsd.h"
 #include "lloptioninterface.h"
 
-#include "google_breakpad/exception_handler.h"
-
 // Forward declarations
 template <typename Type> class LLAtomic32;
 typedef LLAtomic32<U32> LLAtomicU32;
@@ -68,6 +66,10 @@ public:
 };
 #endif
 
+namespace google_breakpad {
+	class ExceptionHandler; // See exception_handler.h
+}
+
 class LL_COMMON_API LLApp : public LLOptionInterface
 {
 	friend class LLErrorThread;
-- 
cgit v1.2.3


From 8f4c8ebcd55c1ad384303802faaa10e33247914f Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 24 May 2010 16:52:12 -0700
Subject: fix darwin build.

---
 indra/llcommon/llapp.cpp | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index e22ff869e7..9e0e8ea814 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -804,6 +804,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
 
 #endif // !WINDOWS
 
+#ifdef LL_DARWIN
 bool darwin_post_minidump_callback(const char *dump_dir,
 					  const char *minidump_id,
 					  void *context, bool succeeded)
@@ -832,7 +833,9 @@ bool darwin_post_minidump_callback(const char *dump_dir,
 	LLApp::runErrorHandler();
 	return true;
 }
+#endif
 
+#ifdef LL_WINDOWS
 bool windows_post_minidump_callback(const wchar_t* dump_path,
 									const wchar_t* minidump_id,
 									void* context,
@@ -882,3 +885,4 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
 
 	return true;
 }
+#endif
\ No newline at end of file
-- 
cgit v1.2.3


From 45a86b67518a579b166e1cf6a719d4aed4c35a39 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Mon, 24 May 2010 16:53:10 -0700
Subject: fix eof newline

---
 indra/llcommon/llapp.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 9e0e8ea814..9ea1a18e5f 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -885,4 +885,4 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
 
 	return true;
 }
-#endif
\ No newline at end of file
+#endif
-- 
cgit v1.2.3


From 5a52c5eb8a5cc4e1215911bac9121891dd802d45 Mon Sep 17 00:00:00 2001
From: "Andrew A. de Laix" <alain@lindenlab.com>
Date: Tue, 25 May 2010 13:32:12 -0700
Subject: Mac crash behavior matches windows and linux: report on crash (not
 after restart).  This is OK because we use Breakpad generated minidumps
 instead of OS generated ones.

---
 indra/llcommon/llapp.h | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 725c13866f..8b2dc1ab72 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -235,6 +235,11 @@ public:
 	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
 	static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread.
 	//@}
+	
+	//
+	// Expose exception handler.
+	//
+	google_breakpad::ExceptionHandler * getExceptionHandler(void) { return mExceptionHandler; }
 
 #if !LL_WINDOWS
 	//
-- 
cgit v1.2.3


From a63b6dd93c1ef78e647dbd221a5a3b14ff363102 Mon Sep 17 00:00:00 2001
From: Lynx Linden <lynx@lindenlab.com>
Date: Wed, 26 May 2010 14:43:27 +0100
Subject: Hooked up Google Breakpad for the Linux client too.

Using Alain's Darwin reporter callback was all that was needed.

Also replaced the call that exposed the breakpad exception class
with a call to just write out the minidump, as that was the only
reason for exposing it. Now clients don't need to know about
Google Breakpad.
---
 indra/llcommon/llapp.cpp | 32 ++++++++++----------------------
 indra/llcommon/llapp.h   |  4 ++--
 2 files changed, 12 insertions(+), 24 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 9ea1a18e5f..6f4acd49b1 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -68,7 +68,7 @@ void setup_signals();
 void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 
 // Called by breakpad exception handler after the minidump has been generated.
-bool darwin_post_minidump_callback(const char *dump_dir,
+bool unix_post_minidump_callback(const char *dump_dir,
 					  const char *minidump_id,
 					  void *context, bool succeeded);
 # if LL_DARWIN
@@ -282,19 +282,11 @@ void LLApp::setupErrorHandling()
 	// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
 
 #if LL_WINDOWS
-	// Windows doesn't have the same signal handling mechanisms as UNIX, thus APR doesn't provide
-	// a signal handling thread implementation.
-	// What we do is install an unhandled exception handler, which will try to do the right thing
-	// in the case of an error (generate a minidump)
-
-	// Disable this until the viewer gets ported so server crashes can be JIT debugged.
-	//LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
-	//prev_filter = SetUnhandledExceptionFilter(default_windows_exception_handler);
-
 	// This sets a callback to handle w32 signals to the console window.
 	// The viewer shouldn't be affected, sicne its a windowed app.
 	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE);
 
+	// Install the Google Breakpad crash handler for Windows
 	if(mExceptionHandler == 0)
 	{
 		llwarns << "adding breakpad exception handler" << llendl;
@@ -309,18 +301,14 @@ void LLApp::setupErrorHandling()
 	// There are two different classes of signals.  Synchronous signals are delivered to a specific
 	// thread, asynchronous signals can be delivered to any thread (in theory)
 	//
-
 	setup_signals();
-
 	
-#ifdef LL_DARWIN
-	// Add google breakpad exception handler configured for Darwin.
+	// Add google breakpad exception handler configured for Darwin/Linux.
 	if(mExceptionHandler == 0)
 	{
 		std::string dumpPath = "/tmp/";
-		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &darwin_post_minidump_callback, 0, true);
+		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true);
 	}
-#endif
 #endif
 
 	startErrorThread();
@@ -373,7 +361,6 @@ void LLApp::runErrorHandler()
 	LLApp::setStopped();
 }
 
-
 // static
 void LLApp::setStatus(EAppStatus status)
 {
@@ -393,6 +380,10 @@ void LLApp::setError()
 	}
 }
 
+void LLApp::writeMiniDump()
+{
+	mExceptionHandler->WriteMinidump();
+}
 
 // static
 void LLApp::setQuitting()
@@ -802,10 +793,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
 	}
 }
 
-#endif // !WINDOWS
-
-#ifdef LL_DARWIN
-bool darwin_post_minidump_callback(const char *dump_dir,
+bool unix_post_minidump_callback(const char *dump_dir,
 					  const char *minidump_id,
 					  void *context, bool succeeded)
 {
@@ -833,7 +821,7 @@ bool darwin_post_minidump_callback(const char *dump_dir,
 	LLApp::runErrorHandler();
 	return true;
 }
-#endif
+#endif // !WINDOWS
 
 #ifdef LL_WINDOWS
 bool windows_post_minidump_callback(const wchar_t* dump_path,
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 8b2dc1ab72..7b1144ebf1 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -237,9 +237,9 @@ public:
 	//@}
 	
 	//
-	// Expose exception handler.
+	// Write out a Google Breakpad minidump file.
 	//
-	google_breakpad::ExceptionHandler * getExceptionHandler(void) { return mExceptionHandler; }
+	void writeMiniDump();
 
 #if !LL_WINDOWS
 	//
-- 
cgit v1.2.3


From 05761d785335f08dc176aa6ebb7f0cd45d1298ab Mon Sep 17 00:00:00 2001
From: Lynx Linden <lynx@lindenlab.com>
Date: Thu, 27 May 2010 15:04:06 +0100
Subject: Removed the SyncErrorHandler from llapp and llappviewer*.

This was only used for the Linux client to dump a stack trace to
stack_trace.log, which is no longer needed now that we are using
Google Breakpad.

I also removed all of the stack printing code from llappviewerlinux.cpp.
---
 indra/llcommon/llapp.cpp | 25 ++-----------------------
 indra/llcommon/llapp.h   |  3 ---
 2 files changed, 2 insertions(+), 26 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 6f4acd49b1..da14020f2b 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -96,7 +96,6 @@ BOOL LLApp::sLogInSignal = FALSE;
 // static
 LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
 LLAppErrorHandler LLApp::sErrorHandler = NULL;
-LLAppErrorHandler LLApp::sSyncErrorHandler = NULL;
 BOOL LLApp::sErrorThreadRunning = FALSE;
 #if !LL_WINDOWS
 LLApp::child_map LLApp::sChildMap;
@@ -334,21 +333,6 @@ void LLApp::setErrorHandler(LLAppErrorHandler handler)
 	LLApp::sErrorHandler = handler;
 }
 
-
-void LLApp::setSyncErrorHandler(LLAppErrorHandler handler)
-{
-	LLApp::sSyncErrorHandler = handler;
-}
-
-// static
-void LLApp::runSyncErrorHandler()
-{
-	if (LLApp::sSyncErrorHandler)
-	{
-		LLApp::sSyncErrorHandler();
-	}
-}
-
 // static
 void LLApp::runErrorHandler()
 {
@@ -371,13 +355,8 @@ void LLApp::setStatus(EAppStatus status)
 // static
 void LLApp::setError()
 {
-	if (!isError())
-	{
-		// perform any needed synchronous error-handling
-		runSyncErrorHandler();
-		// set app status to ERROR so that the LLErrorThread notices
-		setStatus(APP_STATUS_ERROR);
-	}
+	// set app status to ERROR so that the LLErrorThread notices
+	setStatus(APP_STATUS_ERROR);
 }
 
 void LLApp::writeMiniDump()
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 7b1144ebf1..a6294a5e1a 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -231,9 +231,7 @@ public:
 	void setupErrorHandling();
 
 	void setErrorHandler(LLAppErrorHandler handler);
-	void setSyncErrorHandler(LLAppErrorHandler handler);
 	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
-	static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread.
 	//@}
 	
 	//
@@ -306,7 +304,6 @@ private:
 	// their own purposes
 	typedef int(*signal_handler_func)(int signum);
 	static LLAppErrorHandler sErrorHandler;
-	static LLAppErrorHandler sSyncErrorHandler;
 
 	// Default application threads
 	LLErrorThread* mThreadErrorp;		// Waits for app to go to status ERROR, then runs the error callback
-- 
cgit v1.2.3


From 4fb77380279bdf853b7f213ba8997511720468dd Mon Sep 17 00:00:00 2001
From: Lynx Linden <lynx@lindenlab.com>
Date: Fri, 28 May 2010 15:10:52 +0100
Subject: Write breakpad minidump files to the SL log directory. Also, clean
 out old minidump files when we start up.

---
 indra/llcommon/llapp.cpp | 38 ++++++++++++++++++++++++++++++--------
 indra/llcommon/llapp.h   | 16 +++++++++++-----
 2 files changed, 41 insertions(+), 13 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index da14020f2b..861122a4ac 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -140,6 +140,8 @@ void LLApp::commonCtor()
 	
 	mExceptionHandler = 0;
 	
+	// initialize the buffer to write the minidump filename to
+	// (this is used to avoid allocating memory in the crash handler)
 	memset(minidump_path, 0, MAX_MINDUMP_PATH_LENGTH);
 }
 
@@ -359,8 +361,15 @@ void LLApp::setError()
 	setStatus(APP_STATUS_ERROR);
 }
 
+void LLApp::setMiniDumpDir(const std::string &path)
+{
+	llassert(mExceptionHandler);
+	mExceptionHandler->set_dump_path(path);
+}
+
 void LLApp::writeMiniDump()
 {
+	llassert(mExceptionHandler);
 	mExceptionHandler->WriteMinidump();
 }
 
@@ -786,17 +795,25 @@ bool unix_post_minidump_callback(const char *dump_dir,
 	// The path must not be truncated.
 	llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
 	
-	char * path = LLApp::instance()->minidump_path;
+	char * path = LLApp::instance()->getMiniDumpFilename();
 	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
 	strncpy(path, dump_dir, remaining);
 	remaining -= dirPathLength;
 	path += dirPathLength;
-	strncpy(path, minidump_id, remaining);
-	remaining -= idLength;
-	path += idLength;
-	strncpy(path, ".dmp", remaining);
+	if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
+	{
+		*path++ = '/';
+		--remaining;
+	}
+	if (remaining > 0)
+	{
+		strncpy(path, minidump_id, remaining);
+		remaining -= idLength;
+		path += idLength;
+		strncpy(path, ".dmp", remaining);
+	}
 	
-	llinfos << "generated minidump: " << LLApp::instance()->minidump_path << llendl;
+	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
 	LLApp::runErrorHandler();
 	return true;
 }
@@ -810,13 +827,18 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
 									MDRawAssertionInfo* assertion,
 									bool succeeded)
 {
-	char * path = LLApp::instance()->minidump_path;
+	char * path = LLApp::instance()->getMiniDumpFilename();
 	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
 	size_t bytesUsed;
 
 	bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining));
 	remaining -= bytesUsed;
 	path += bytesUsed;
+	if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\')
+	{
+		*path++ = '\\';
+		--remaining;
+	}
 	if(remaining > 0)
 	{
 		bytesUsed = wcstombs(path, minidump_id, static_cast<size_t>(remaining));
@@ -828,7 +850,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
 		strncpy(path, ".dmp", remaining);
 	}
 
-	llinfos << "generated minidump: " << LLApp::instance()->minidump_path << llendl;
+	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
     // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
 	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
     // *TODO: Translate the signals/exceptions into cross-platform stuff
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index a6294a5e1a..fef05a7939 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -234,9 +234,16 @@ public:
 	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
 	//@}
 	
-	//
+	// the maximum length of the minidump filename returned by getMiniDumpFilename()
+	static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
+
+	// change the directory where Breakpad minidump files are written to
+	void setMiniDumpDir(const std::string &path);
+
+	// Return the Google Breakpad minidump filename after a crash.
+	char *getMiniDumpFilename() { return minidump_path; }
+
 	// Write out a Google Breakpad minidump file.
-	//
 	void writeMiniDump();
 
 #if !LL_WINDOWS
@@ -274,9 +281,6 @@ public:
 	typedef std::map<std::string, std::string> string_map;
 	string_map mOptionMap;	// Contains all command-line options and arguments in a map
 
-	// Contains the path to minidump file after a crash.
-	static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
-	char minidump_path[MAX_MINDUMP_PATH_LENGTH];
 protected:
 
 	static void setStatus(EAppStatus status);		// Use this to change the application status.
@@ -298,6 +302,8 @@ protected:
 private:
 	void startErrorThread();
 	
+	// Contains the filename of the minidump file after a crash.
+	char minidump_path[MAX_MINDUMP_PATH_LENGTH];
 
 	// *NOTE: On Windows, we need a routine to reset the structured
 	// exception handler when some evil driver has taken it over for
-- 
cgit v1.2.3


From 590a3d891c138f881d7a3f7c2758e778256e3891 Mon Sep 17 00:00:00 2001
From: Lynx Linden <lynx@lindenlab.com>
Date: Fri, 28 May 2010 15:40:16 +0100
Subject: On Windows, you have to pass the minidump path as a wstring.

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

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 861122a4ac..1ea888f2e0 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -43,6 +43,7 @@
 #include "lllivefile.h"
 #include "llmemory.h"
 #include "llstl.h" // for DeletePointer()
+#include "llstring.h"
 #include "lleventtimer.h"
 
 #include "google_breakpad/exception_handler.h"
@@ -364,7 +365,11 @@ void LLApp::setError()
 void LLApp::setMiniDumpDir(const std::string &path)
 {
 	llassert(mExceptionHandler);
+#ifdef LL_WINDOWS
+	mExceptionHandler->set_dump_path(utf8str_to_wstring(path));
+#else
 	mExceptionHandler->set_dump_path(path);
+#endif
 }
 
 void LLApp::writeMiniDump()
-- 
cgit v1.2.3


From 80d9cde59656964335613f99dfa63bb834278416 Mon Sep 17 00:00:00 2001
From: Lynx Linden <lynx@lindenlab.com>
Date: Fri, 28 May 2010 16:15:00 +0100
Subject: Try using mbstowcs() to convert to std::wstring. LLWString cannot be
 converted to std::wstring, apparently.

---
 indra/llcommon/llapp.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 1ea888f2e0..eedec0b24e 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -366,7 +366,9 @@ void LLApp::setMiniDumpDir(const std::string &path)
 {
 	llassert(mExceptionHandler);
 #ifdef LL_WINDOWS
-	mExceptionHandler->set_dump_path(utf8str_to_wstring(path));
+	wchar_t buffer[MAX_MINDUMP_PATH_LENGTH];
+	mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH);
+	mExceptionHandler->set_dump_path(std::wstring(buffer));
 #else
 	mExceptionHandler->set_dump_path(path);
 #endif
-- 
cgit v1.2.3