summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew A. de Laix <alain@lindenlab.com>2010-05-24 15:19:33 -0700
committerAndrew A. de Laix <alain@lindenlab.com>2010-05-24 15:19:33 -0700
commit1077ab49c171c0f310f9b76b360ea2ad162a31ff (patch)
tree475225176d08d1ae0620c260bfb7353916c3cbca
parent168fbc9b37923873aeb6d87d71d9e33064f46351 (diff)
Just enough hackery to get minidumps into Wind'ohs crash reports. Code clean up needed.
-rw-r--r--indra/cmake/GoogleBreakpad.cmake31
-rw-r--r--indra/llcommon/llapp.cpp67
-rw-r--r--indra/llcommon/llapp.h6
-rw-r--r--indra/newview/llappviewerwin32.cpp5
-rw-r--r--indra/newview/llwindebug.cpp28
5 files changed, 102 insertions, 35 deletions
diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake
index 0b9f4a00d0..b21b733500 100644
--- a/indra/cmake/GoogleBreakpad.cmake
+++ b/indra/cmake/GoogleBreakpad.cmake
@@ -1,14 +1,17 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-if (STANDALONE)
- MESSAGE(FATAL_ERROR "*TODO standalone support for google breakad is unimplemented")
- # *TODO - implement this include(FindGoogleBreakpad)
-else (STANDALONE)
- use_prebuilt_binary(google_breakpad)
- set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client common)
- if (LINUX)
- set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client)
- endif (LINUX)
-endif (STANDALONE)
-
+# -*- cmake -*-
+include(Prebuilt)
+
+if (STANDALONE)
+ MESSAGE(FATAL_ERROR "*TODO standalone support for google breakad is unimplemented")
+ # *TODO - implement this include(FindGoogleBreakpad)
+else (STANDALONE)
+ use_prebuilt_binary(google_breakpad)
+ set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler)
+ if(WINDOWS)
+ list(APPEND BREAKPAD_EXCEPTION_HANDLER_LIBRARIES crash_generation_client common)
+ endif(WINDOWS)
+ if (LINUX)
+ set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client)
+ endif (LINUX)
+endif (STANDALONE)
+
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;
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 60a6d2f072..4bee8d9ac5 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -529,8 +529,9 @@ bool LLAppViewerWin32::initParseCommandLine(LLCommandLineParser& clp)
}
bool LLAppViewerWin32::restoreErrorTrap()
-{
- return LLWinDebug::checkExceptionHandler();
+{
+ return true;
+ //return LLWinDebug::checkExceptionHandler();
}
void LLAppViewerWin32::handleSyncCrashTrace()
diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp
index 59bc9dc62b..9f8585f163 100644
--- a/indra/newview/llwindebug.cpp
+++ b/indra/newview/llwindebug.cpp
@@ -718,7 +718,8 @@ BOOL PreventSetUnhandledExceptionFilter()
// static
void LLWinDebug::initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func)
{
-
+ return;
+#if 0
static bool s_first_run = true;
// Load the dbghelp dll now, instead of waiting for the crash.
// Less potential for stack mangling
@@ -762,34 +763,27 @@ void LLWinDebug::initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func)
Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32FirstW");
Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32NextW");
- LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
- prev_filter = SetUnhandledExceptionFilter(filter_func);
-
- // *REMOVE:Mani
- //PreventSetUnhandledExceptionFilter();
+ PVOID added_filter =
+ AddVectoredExceptionHandler(0, filter_func);
- if(prev_filter != gFilterFunc)
+ if(added_filter == 0)
{
LL_WARNS("AppInit")
- << "Replacing unknown exception (" << (void *)prev_filter << ") with (" << (void *)filter_func << ") !" << LL_ENDL;
+ << "Failed to add exception handler (" << added_filter << ") !" << LL_ENDL;
}
gFilterFunc = filter_func;
+#endif
}
bool LLWinDebug::checkExceptionHandler()
{
bool ok = true;
- LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
- prev_filter = SetUnhandledExceptionFilter(gFilterFunc);
- if (prev_filter != gFilterFunc)
- {
- LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with " << prev_filter << "!" << LL_ENDL;
- ok = false;
- }
+ RemoveVectoredExceptionHandler(gFilterFunc);
+ PVOID filter = AddVectoredExceptionHandler(0, gFilterFunc);
- if (prev_filter == NULL)
+ if (filter == NULL)
{
ok = FALSE;
if (gFilterFunc == NULL)
@@ -798,7 +792,7 @@ bool LLWinDebug::checkExceptionHandler()
}
else
{
- LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with NULL!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Failed to add exception handler (" << (void *)gFilterFunc << ")!" << LL_ENDL;
}
}