summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewerlinux.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2008-04-17 02:42:27 +0000
committerSteven Bennetts <steve@lindenlab.com>2008-04-17 02:42:27 +0000
commitd85247e63e5ff0b488211b62429a4895b48dee27 (patch)
tree0aa2f02aeef6a8133e0d037e95ad5089b20df9eb /indra/newview/llappviewerlinux.cpp
parentd2597d35cf3aeaf0c47a134dfe9119ef7932b98a (diff)
QAR-449 Viewer 1.20 RC 0
merge Branch_1-20-Viewer -r 84060 : 84432 -> release
Diffstat (limited to 'indra/newview/llappviewerlinux.cpp')
-rw-r--r--indra/newview/llappviewerlinux.cpp73
1 files changed, 48 insertions, 25 deletions
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index c36dd2955e..d7a8e66a4b 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -39,27 +39,41 @@
#include "llviewernetwork.h"
#include "llmd5.h"
- #if LL_LINUX
- # include <dlfcn.h> // RTLD_LAZY
- # include <execinfo.h> // backtrace - glibc only
- # ifndef LL_ELFBIN
- #define LL_ELFBIN 1
- # endif // LL_ELFBIN
- # if LL_ELFBIN
- # include <cxxabi.h> // for symbol demangling
- # include "ELFIO.h" // for better backtraces
- # endif // LL_ELFBIN
- #elif LL_SOLARIS
- # include <sys/types.h>
- # include <unistd.h>
- # include <fcntl.h>
- # include <ucontext.h>
- #endif
+#include <exception>
+
+#if LL_LINUX
+# include <dlfcn.h> // RTLD_LAZY
+# include <execinfo.h> // backtrace - glibc only
+# ifndef LL_ELFBIN
+# define LL_ELFBIN 1
+# endif // LL_ELFBIN
+# if LL_ELFBIN
+# include <cxxabi.h> // for symbol demangling
+# include "ELFIO.h" // for better backtraces
+# endif // LL_ELFBIN
+#elif LL_SOLARIS
+# include <sys/types.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <ucontext.h>
+#endif
namespace
{
int gArgC = 0;
char **gArgV = NULL;
+ void (*gOldTerminateHandler)() = NULL;
+}
+
+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
}
int main( int argc, char **argv )
@@ -75,7 +89,11 @@ int main( int argc, char **argv )
LLAppViewer* viewer_app_ptr = new LLAppViewerLinux();
+ // install unexpected exception handler
+ 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)
@@ -301,19 +319,22 @@ bool LLAppViewerLinux::init()
return LLAppViewer::init();
}
-void LLAppViewerLinux::handleCrashReporting()
+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()
+{
// Always generate the report, have the logger do the asking, and
// don't wait for the logger before exiting (-> total cleanup).
if (CRASH_BEHAVIOR_NEVER_SEND != LLAppViewer::instance()->getCrashBehavior())
{
- // 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
// launch the actual crash logger
char* ask_dialog = "-dialog";
if (CRASH_BEHAVIOR_ASK != LLAppViewer::instance()->getCrashBehavior())
@@ -329,6 +350,7 @@ void LLAppViewerLinux::handleCrashReporting()
(char*)"-name",
(char*)LLAppViewer::instance()->getSecondLifeTitle().c_str(),
NULL};
+ fflush(NULL);
pid_t pid = fork();
if (pid == 0)
{ // child
@@ -352,9 +374,10 @@ void LLAppViewerLinux::handleCrashReporting()
}
}
}
- // Sometimes signals don't seem to quit the viewer.
+ // Sometimes signals don't seem to quit the viewer. Also, we may
+ // have been called explicitly instead of from a signal handler.
// Make sure we exit so as to not totally confuse the user.
- exit(1);
+ _exit(1); // avoid atexit(), else we may re-crash in dtors.
}
bool LLAppViewerLinux::beingDebugged()