diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llappviewerlinux.cpp | 103 |
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 | |||
61 | namespace | ||
62 | { | ||
63 | int gArgC = 0; | ||
64 | char **gArgV = NULL; | ||
65 | void (*gOldTerminateHandler)() = NULL; | ||
66 | } | ||
67 | |||
68 | static 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 | ||
57 | int main( int argc, char **argv ) | 79 | int 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 | ||
300 | void LLAppViewerLinux::handleCrashReporting() | 322 | void 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 | ||
332 | void 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 | ||
356 | bool LLAppViewerLinux::beingDebugged() | 383 | bool LLAppViewerLinux::beingDebugged() |
@@ -403,6 +430,12 @@ bool LLAppViewerLinux::initLogging() | |||
403 | return LLAppViewer::initLogging(); | 430 | return LLAppViewer::initLogging(); |
404 | } | 431 | } |
405 | 432 | ||
433 | bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp) | ||
434 | { | ||
435 | clp.parseCommandLine(gArgC, gArgV); | ||
436 | return true; | ||
437 | } | ||
438 | |||
406 | std::string LLAppViewerLinux::generateSerialNumber() | 439 | std::string LLAppViewerLinux::generateSerialNumber() |
407 | { | 440 | { |
408 | char serial_md5[MD5HEX_STR_SIZE]; | 441 | char serial_md5[MD5HEX_STR_SIZE]; |