From 719edddf0498752a0295502d62710823d1a72cc7 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Fri, 21 May 2010 09:38:29 -0700 Subject: Switch Darwin to use breakpad minidump rather than os generated crash stack. --- indra/llcommon/llapp.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/llapp.cpp') 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 // 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: /.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; +} -- cgit v1.3 From 1077ab49c171c0f310f9b76b360ea2ad162a31ff Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" 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/cmake/GoogleBreakpad.cmake | 31 ++++++++++-------- indra/llcommon/llapp.cpp | 67 ++++++++++++++++++++++++++++++++++++++ indra/llcommon/llapp.h | 6 ++-- indra/newview/llappviewerwin32.cpp | 5 +-- indra/newview/llwindebug.cpp | 28 +++++++--------- 5 files changed, 102 insertions(+), 35 deletions(-) (limited to 'indra/llcommon/llapp.cpp') 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 + #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 # include // 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(remaining)); + remaining -= bytesUsed; + path += bytesUsed; + if(remaining > 0) + { + bytesUsed = wcstombs(path, minidump_id, static_cast(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 class LLAtomic32; typedef LLAtomic32 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; } } -- cgit v1.3 From 8f4c8ebcd55c1ad384303802faaa10e33247914f Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" 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/llapp.cpp') 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.3 From 45a86b67518a579b166e1cf6a719d4aed4c35a39 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" 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/llapp.cpp') 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.3 From a63b6dd93c1ef78e647dbd221a5a3b14ff363102 Mon Sep 17 00:00:00 2001 From: Lynx Linden 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 ++-- indra/newview/llappviewer.cpp | 8 +++++--- 3 files changed, 17 insertions(+), 27 deletions(-) (limited to 'indra/llcommon/llapp.cpp') 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 // diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7cdd8ca309..0484659793 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -102,7 +102,6 @@ // Third party library includes #include -#include #if LL_WINDOWS @@ -2582,7 +2581,10 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); - if(pApp->minidump_path[0] != 0) gDebugInfo["MinidumpPath"] = pApp->minidump_path; + if(pApp->minidump_path[0] != 0) + { + gDebugInfo["MinidumpPath"] = pApp->minidump_path; + } if(gLogoutInProgress) { @@ -3290,7 +3292,7 @@ void LLAppViewer::badNetworkHandler() "www.secondlife.com/support"; forceDisconnect(message.str()); - LLApp::instance()->getExceptionHandler()->WriteMinidump(); + LLApp::instance()->writeMiniDump(); } // This routine may get called more than once during the shutdown process. -- cgit v1.3 From 05761d785335f08dc176aa6ebb7f0cd45d1298ab Mon Sep 17 00:00:00 2001 From: Lynx Linden 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 - indra/newview/llappviewer.cpp | 7 -- indra/newview/llappviewer.h | 2 - indra/newview/llappviewerlinux.cpp | 224 ------------------------------------ indra/newview/llappviewerlinux.h | 1 - indra/newview/llappviewermacosx.cpp | 5 - indra/newview/llappviewermacosx.h | 1 - indra/newview/llappviewerwin32.cpp | 5 - indra/newview/llappviewerwin32.h | 1 - 10 files changed, 2 insertions(+), 272 deletions(-) (limited to 'indra/llcommon/llapp.cpp') 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 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0484659793..1ad180a024 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2513,13 +2513,6 @@ void LLAppViewer::writeSystemInfo() writeDebugInfo(); // Save out debug_info.log early, in case of crash. } -void LLAppViewer::handleSyncViewerCrash() -{ - LLAppViewer* pApp = LLAppViewer::instance(); - // Call to pure virtual, handled by platform specific llappviewer instance. - pApp->handleSyncCrashTrace(); -} - void LLAppViewer::handleViewerCrash() { llinfos << "Handle viewer crash entry." << llendl; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5acd6e11c4..0b862a92a1 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -92,9 +92,7 @@ public: virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism. // return false if the error trap needed restoration. virtual void handleCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? - virtual void handleSyncCrashTrace() = 0; // any low-level crash-prep that has to happen in the context of the crashing thread before the crash report is delivered. static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. - static void handleSyncViewerCrash(); // Hey! The viewer crashed. Do this right NOW in the context of the crashing thread. void checkForCrash(); // Thread accessors diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 78b0f7ba83..ba9a4e4a6e 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -46,23 +46,6 @@ #include -#if LL_LINUX -# include // RTLD_LAZY -# include // backtrace - glibc only -#elif LL_SOLARIS -# include -# include -# include -# include -#endif - -#ifdef LL_ELFBIN -# ifdef __GNUC__ -# include // for symbol demangling -# endif -# include "ELFIO/ELFIO.h" // for better backtraces -#endif - #if LL_DBUS_ENABLED # include "llappviewerlinux_api_dbus.h" @@ -86,7 +69,6 @@ static void exceptionTerminateHandler() // reinstall default terminate() handler in case we re-terminate. if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); // treat this like a regular viewer crash, with nice stacktrace etc. - LLAppViewer::handleSyncViewerCrash(); LLAppViewer::handleViewerCrash(); // we've probably been killed-off before now, but... gOldTerminateHandler(); // call old terminate() handler @@ -109,7 +91,6 @@ int main( int argc, char **argv ) gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); // install crash handlers viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); - viewer_app_ptr->setSyncErrorHandler(LLAppViewer::handleSyncViewerCrash); bool ok = viewer_app_ptr->init(); if(!ok) @@ -138,201 +119,6 @@ int main( int argc, char **argv ) return 0; } -#ifdef LL_SOLARIS -static inline BOOL do_basic_glibc_backtrace() -{ - BOOL success = FALSE; - - std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); - llinfos << "Opening stack trace file " << strace_filename << llendl; - LLFILE* StraceFile = LLFile::fopen(strace_filename, "w"); - if (!StraceFile) - { - llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; - StraceFile = stderr; - } - - printstack(fileno(StraceFile)); - - if (StraceFile != stderr) - fclose(StraceFile); - - return success; -} -#else -#define MAX_STACK_TRACE_DEPTH 40 -// This uses glibc's basic built-in stack-trace functions for a not very -// amazing backtrace. -static inline BOOL do_basic_glibc_backtrace() -{ - void *stackarray[MAX_STACK_TRACE_DEPTH]; - size_t size; - char **strings; - size_t i; - BOOL success = FALSE; - - size = backtrace(stackarray, MAX_STACK_TRACE_DEPTH); - strings = backtrace_symbols(stackarray, size); - - std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); - llinfos << "Opening stack trace file " << strace_filename << llendl; - LLFILE* StraceFile = LLFile::fopen(strace_filename, "w"); // Flawfinder: ignore - if (!StraceFile) - { - llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; - StraceFile = stderr; - } - - if (size) - { - for (i = 0; i < size; i++) - { - // the format of the StraceFile is very specific, to allow (kludgy) machine-parsing - fprintf(StraceFile, "%-3lu ", (unsigned long)i); - fprintf(StraceFile, "%-32s\t", "unknown"); - fprintf(StraceFile, "%p ", stackarray[i]); - fprintf(StraceFile, "%s\n", strings[i]); - } - - success = TRUE; - } - - if (StraceFile != stderr) - fclose(StraceFile); - - free (strings); - return success; -} - -#if LL_ELFBIN -// This uses glibc's basic built-in stack-trace functions together with -// ELFIO's ability to parse the .symtab ELF section for better symbol -// extraction without exporting symbols (which'd cause subtle, fatal bugs). -static inline BOOL do_elfio_glibc_backtrace() -{ - void *stackarray[MAX_STACK_TRACE_DEPTH]; - size_t btsize; - char **strings; - BOOL success = FALSE; - - std::string appfilename = gDirUtilp->getExecutablePathAndName(); - - std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); - llinfos << "Opening stack trace file " << strace_filename << llendl; - LLFILE* StraceFile = LLFile::fopen(strace_filename, "w"); // Flawfinder: ignore - if (!StraceFile) - { - llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; - StraceFile = stderr; - } - - // get backtrace address list and basic symbol info - btsize = backtrace(stackarray, MAX_STACK_TRACE_DEPTH); - strings = backtrace_symbols(stackarray, btsize); - - // create ELF reader for our app binary - IELFI* pReader; - const IELFISection* pSec = NULL; - IELFISymbolTable* pSymTbl = 0; - if (ERR_ELFIO_NO_ERROR != ELFIO::GetInstance()->CreateELFI(&pReader) || - ERR_ELFIO_NO_ERROR != pReader->Load(appfilename.c_str()) || - // find symbol table, create reader-object - NULL == (pSec = pReader->GetSection( ".symtab" )) || - ERR_ELFIO_NO_ERROR != pReader->CreateSectionReader(IELFI::ELFI_SYMBOL, pSec, (void**)&pSymTbl) ) - { - // Failed to open our binary and read its symbol table somehow - llinfos << "Could not initialize ELF symbol reading - doing basic backtrace." << llendl; - if (StraceFile != stderr) - fclose(StraceFile); - // note that we may be leaking some of the above ELFIO - // objects now, but it's expected that we'll be dead soon - // and we want to tread delicately until we get *some* kind - // of useful backtrace. - return do_basic_glibc_backtrace(); - } - - // iterate over trace and symtab, looking for plausible symbols - std::string name; - Elf32_Addr value; - Elf32_Word ssize; - unsigned char bind; - unsigned char type; - Elf32_Half section; - int nSymNo = pSymTbl->GetSymbolNum(); - size_t btpos; - for (btpos = 0; btpos < btsize; ++btpos) - { - // the format of the StraceFile is very specific, to allow (kludgy) machine-parsing - fprintf(StraceFile, "%-3ld ", (long)btpos); - int symidx; - for (symidx = 0; symidx < nSymNo; ++symidx) - { - if (ERR_ELFIO_NO_ERROR == - pSymTbl->GetSymbol(symidx, name, value, ssize, - bind, type, section)) - { - // check if trace address within symbol range - if (uintptr_t(stackarray[btpos]) >= value && - uintptr_t(stackarray[btpos]) < value+ssize) - { - // symbol is inside viewer - fprintf(StraceFile, "%-32s\t", "com.secondlife.indra.viewer"); - fprintf(StraceFile, "%p ", stackarray[btpos]); - - char *demangled_str = NULL; - int demangle_result = 1; - demangled_str = - abi::__cxa_demangle - (name.c_str(), NULL, NULL, - &demangle_result); - if (0 == demangle_result && - NULL != demangled_str) { - fprintf(StraceFile, - "%s", demangled_str); - free(demangled_str); - } - else // failed demangle; print it raw - { - fprintf(StraceFile, - "%s", name.c_str()); - } - // print offset from symbol start - fprintf(StraceFile, - " + %lu\n", - uintptr_t(stackarray[btpos]) - - value); - goto got_sym; // early escape - } - } - } - // Fallback: - // Didn't find a suitable symbol in the binary - it's probably - // a symbol in a DSO; use glibc's idea of what it should be. - fprintf(StraceFile, "%-32s\t", "unknown"); - fprintf(StraceFile, "%p ", stackarray[btpos]); - fprintf(StraceFile, "%s\n", strings[btpos]); - got_sym:; - } - - if (StraceFile != stderr) - fclose(StraceFile); - - pSymTbl->Release(); - pSec->Release(); - pReader->Release(); - - free(strings); - - llinfos << "Finished generating stack trace." << llendl; - - success = TRUE; - return success; -} -#endif // LL_ELFBIN - -#endif // LL_SOLARIS - - LLAppViewerLinux::LLAppViewerLinux() { } @@ -541,16 +327,6 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) } #endif // LL_DBUS_ENABLED -void LLAppViewerLinux::handleSyncCrashTrace() -{ - // This backtrace writes into stack_trace.log -# if LL_ELFBIN - do_elfio_glibc_backtrace(); // more useful backtrace -# else - do_basic_glibc_backtrace(); // only slightly useful backtrace -# endif // LL_ELFBIN -} - void LLAppViewerLinux::handleCrashReporting(bool reportFreeze) { std::string cmd =gDirUtilp->getExecutableDir(); diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 230c0dc24b..b17380d4d8 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -68,7 +68,6 @@ protected: virtual bool restoreErrorTrap(); virtual void handleCrashReporting(bool reportFreeze); - virtual void handleSyncCrashTrace(); virtual bool initLogging(); virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 2f12ad7e38..1e66e55f3d 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -264,11 +264,6 @@ bool LLAppViewerMacOSX::restoreErrorTrap() return reset_count == 0; } -void LLAppViewerMacOSX::handleSyncCrashTrace() -{ - // do nothing -} - static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData) diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h index cbf7e6c209..3d7bb55556 100644 --- a/indra/newview/llappviewermacosx.h +++ b/indra/newview/llappviewermacosx.h @@ -55,7 +55,6 @@ public: protected: virtual bool restoreErrorTrap(); virtual void handleCrashReporting(bool reportFreeze); - virtual void handleSyncCrashTrace(); std::string generateSerialNumber(); virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 88d8dba8af..e3ef04d03d 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -479,11 +479,6 @@ bool LLAppViewerWin32::restoreErrorTrap() //return LLWinDebug::checkExceptionHandler(); } -void LLAppViewerWin32::handleSyncCrashTrace() -{ - // do nothing -} - void LLAppViewerWin32::handleCrashReporting(bool reportFreeze) { const char* logger_name = "win_crash_logger.exe"; diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 13454edeec..52dcc583a4 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -57,7 +57,6 @@ protected: virtual bool restoreErrorTrap(); virtual void handleCrashReporting(bool reportFreeze); - virtual void handleSyncCrashTrace(); virtual bool sendURLToOtherInstance(const std::string& url); -- cgit v1.3