diff options
author | Andrew A. de Laix <alain@lindenlab.com> | 2010-05-24 15:19:33 -0700 |
---|---|---|
committer | Andrew A. de Laix <alain@lindenlab.com> | 2010-05-24 15:19:33 -0700 |
commit | 1077ab49c171c0f310f9b76b360ea2ad162a31ff (patch) | |
tree | 475225176d08d1ae0620c260bfb7353916c3cbca | |
parent | 168fbc9b37923873aeb6d87d71d9e33064f46351 (diff) |
Just enough hackery to get minidumps into Wind'ohs crash reports. Code clean up needed.
-rw-r--r-- | indra/cmake/GoogleBreakpad.cmake | 31 | ||||
-rw-r--r-- | indra/llcommon/llapp.cpp | 67 | ||||
-rw-r--r-- | indra/llcommon/llapp.h | 6 | ||||
-rw-r--r-- | indra/newview/llappviewerwin32.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llwindebug.cpp | 28 |
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; } } |