diff options
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/llcommon/llapp.cpp | 51 | ||||
-rw-r--r-- | indra/llcommon/llapp.h | 11 | ||||
-rwxr-xr-x | indra/llcrashlogger/llcrashlogger.cpp | 21 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 2 | ||||
-rw-r--r-- | install.xml | 11 |
6 files changed, 92 insertions, 5 deletions
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 diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index c1022c1195..8f5aa5ab2d 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -274,6 +274,27 @@ void LLCrashLogger::gatherFiles() mCrashInfo[(*itr).first] = rawstr_to_utf8(crash_info); } + + // Add minidump as binary. + std::string minidump_path = mDebugLog["MinidumpPath"]; + if(minidump_path != "") + { + std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary); + if(minidump_stream.is_open()) + { + minidump_stream.seekg(0, std::ios::end); + size_t length = minidump_stream.tellg(); + minidump_stream.seekg(0, std::ios::beg); + + LLSD::Binary data; + data.resize(length); + + minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length); + minidump_stream.close(); + + mCrashInfo["Minidump"] = data; + } + } } LLSD LLCrashLogger::constructPostData() diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f7f7cb599e..56486c788b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2587,6 +2587,8 @@ 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(gLogoutInProgress) { gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; diff --git a/install.xml b/install.xml index 1ac6f7d918..e59634fcb2 100644 --- a/install.xml +++ b/install.xml @@ -595,10 +595,17 @@ <map> <key>darwin</key> <map> + <key>i386</key> + <map> + <key>md5sum</key> + <string>84139a373314b85e0c27e13a5263dcc6</string> + <key>url</key> + <uri> http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google_breakpad-0.0.0-rev599-darwin-20100519.tar.bz2</uri> + </map> <key>md5sum</key> - <string>34bb9d8dd8247fdbe238cf96813f333b</string> + <string>c7b20b28a256a74fb646bd2ddbc3ec32</string> <key>url</key> - <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/google_breakpad-0.0.0-rev599-darwin-20100517.tar.bz2</uri> + <uri> http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/google_breakpad-0.0.0-rev599-darwin-20100519a.tar.bz2</uri> </map> <key>windows</key> <map> |