aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llappviewerlinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llappviewerlinux.cpp103
1 files changed, 68 insertions, 35 deletions
diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp
index 659fbf49..084df9b 100644
--- a/linden/indra/newview/llappviewerlinux.cpp
+++ b/linden/indra/newview/llappviewerlinux.cpp
@@ -31,28 +31,50 @@
31 31
32#include "llviewerprecompiledheaders.h" 32#include "llviewerprecompiledheaders.h"
33 33
34#include "llmemtype.h"
35#include "llappviewerlinux.h" 34#include "llappviewerlinux.h"
36 35
36#include "llcommandlineparser.h"
37
38#include "llmemtype.h"
37#include "llviewernetwork.h" 39#include "llviewernetwork.h"
38#include "llmd5.h" 40#include "llmd5.h"
39 41
40 #if LL_LINUX 42#include <exception>
41 # include <dlfcn.h> // RTLD_LAZY 43
42 # include <execinfo.h> // backtrace - glibc only 44#if LL_LINUX
43 # ifndef LL_ELFBIN 45# include <dlfcn.h> // RTLD_LAZY
44 #define LL_ELFBIN 1 46# include <execinfo.h> // backtrace - glibc only
45 # endif // LL_ELFBIN 47# ifndef LL_ELFBIN
46 # if LL_ELFBIN 48# define LL_ELFBIN 1
47 # include <cxxabi.h> // for symbol demangling 49# endif // LL_ELFBIN
48 # include "ELFIO.h" // for better backtraces 50# if LL_ELFBIN
49 # endif // LL_ELFBIN 51# include <cxxabi.h> // for symbol demangling
50 #elif LL_SOLARIS 52# include "ELFIO.h" // for better backtraces
51 # include <sys/types.h> 53# endif // LL_ELFBIN
52 # include <unistd.h> 54#elif LL_SOLARIS
53 # include <fcntl.h> 55# include <sys/types.h>
54 # include <ucontext.h> 56# include <unistd.h>
55 #endif 57# include <fcntl.h>
58# include <ucontext.h>
59#endif
60
61namespace
62{
63 int gArgC = 0;
64 char **gArgV = NULL;
65 void (*gOldTerminateHandler)() = NULL;
66}
67
68static void exceptionTerminateHandler()
69{
70 // reinstall default terminate() handler in case we re-terminate.
71 if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
72 // treat this like a regular viewer crash, with nice stacktrace etc.
73 LLAppViewer::handleSyncViewerCrash();
74 LLAppViewer::handleViewerCrash();
75 // we've probably been killed-off before now, but...
76 gOldTerminateHandler(); // call old terminate() handler
77}
56 78
57int main( int argc, char **argv ) 79int main( int argc, char **argv )
58{ 80{
@@ -62,18 +84,18 @@ int main( int argc, char **argv )
62 asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC 84 asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
63#endif 85#endif
64 86
87 gArgC = argc;
88 gArgV = argv;
89
65 LLAppViewer* viewer_app_ptr = new LLAppViewerLinux(); 90 LLAppViewer* viewer_app_ptr = new LLAppViewerLinux();
66 91
92 // install unexpected exception handler
93 gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
94 // install crash handlers
67 viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); 95 viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
96 viewer_app_ptr->setSyncErrorHandler(LLAppViewer::handleSyncViewerCrash);
68 97
69 bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv); 98 bool ok = viewer_app_ptr->init();
70 if(!ok)
71 {
72 llwarns << "Unable to parse command line." << llendl;
73 return -1;
74 }
75
76 ok = viewer_app_ptr->init();
77 if(!ok) 99 if(!ok)
78 { 100 {
79 llwarns << "Application init failed." << llendl; 101 llwarns << "Application init failed." << llendl;
@@ -297,19 +319,22 @@ bool LLAppViewerLinux::init()
297 return LLAppViewer::init(); 319 return LLAppViewer::init();
298} 320}
299 321
300void LLAppViewerLinux::handleCrashReporting() 322void LLAppViewerLinux::handleSyncCrashTrace()
301{ 323{
324 // This backtrace writes into stack_trace.log
325# if LL_ELFBIN
326 do_elfio_glibc_backtrace(); // more useful backtrace
327# else
328 do_basic_glibc_backtrace(); // only slightly useful backtrace
329# endif // LL_ELFBIN
330}
302 331
332void LLAppViewerLinux::handleCrashReporting()
333{
303 // Always generate the report, have the logger do the asking, and 334 // Always generate the report, have the logger do the asking, and
304 // don't wait for the logger before exiting (-> total cleanup). 335 // don't wait for the logger before exiting (-> total cleanup).
305 if (CRASH_BEHAVIOR_NEVER_SEND != LLAppViewer::instance()->getCrashBehavior()) 336 if (CRASH_BEHAVIOR_NEVER_SEND != LLAppViewer::instance()->getCrashBehavior())
306 { 337 {
307 // This backtrace writes into stack_trace.log
308# if LL_ELFBIN
309 do_elfio_glibc_backtrace(); // more useful backtrace
310# else
311 do_basic_glibc_backtrace(); // only slightly useful backtrace
312# endif // LL_ELFBIN
313 // launch the actual crash logger 338 // launch the actual crash logger
314 char* ask_dialog = "-dialog"; 339 char* ask_dialog = "-dialog";
315 if (CRASH_BEHAVIOR_ASK != LLAppViewer::instance()->getCrashBehavior()) 340 if (CRASH_BEHAVIOR_ASK != LLAppViewer::instance()->getCrashBehavior())
@@ -321,10 +346,11 @@ void LLAppViewerLinux::handleCrashReporting()
321 {(char*)cmd.c_str(), 346 {(char*)cmd.c_str(),
322 ask_dialog, 347 ask_dialog,
323 (char*)"-user", 348 (char*)"-user",
324 (char*)gGridName, 349 (char*)gGridName.c_str(),
325 (char*)"-name", 350 (char*)"-name",
326 (char*)LLAppViewer::instance()->getSecondLifeTitle().c_str(), 351 (char*)LLAppViewer::instance()->getSecondLifeTitle().c_str(),
327 NULL}; 352 NULL};
353 fflush(NULL);
328 pid_t pid = fork(); 354 pid_t pid = fork();
329 if (pid == 0) 355 if (pid == 0)
330 { // child 356 { // child
@@ -348,9 +374,10 @@ void LLAppViewerLinux::handleCrashReporting()
348 } 374 }
349 } 375 }
350 } 376 }
351 // Sometimes signals don't seem to quit the viewer. 377 // Sometimes signals don't seem to quit the viewer. Also, we may
378 // have been called explicitly instead of from a signal handler.
352 // Make sure we exit so as to not totally confuse the user. 379 // Make sure we exit so as to not totally confuse the user.
353 exit(1); 380 _exit(1); // avoid atexit(), else we may re-crash in dtors.
354} 381}
355 382
356bool LLAppViewerLinux::beingDebugged() 383bool LLAppViewerLinux::beingDebugged()
@@ -403,6 +430,12 @@ bool LLAppViewerLinux::initLogging()
403 return LLAppViewer::initLogging(); 430 return LLAppViewer::initLogging();
404} 431}
405 432
433bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp)
434{
435 clp.parseCommandLine(gArgC, gArgV);
436 return true;
437}
438
406std::string LLAppViewerLinux::generateSerialNumber() 439std::string LLAppViewerLinux::generateSerialNumber()
407{ 440{
408 char serial_md5[MD5HEX_STR_SIZE]; 441 char serial_md5[MD5HEX_STR_SIZE];