diff options
| -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;  		}  	}  | 
