aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llapp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llapp.cpp')
-rw-r--r--linden/indra/llcommon/llapp.cpp163
1 files changed, 92 insertions, 71 deletions
diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp
index bd2e377..ebace4e 100644
--- a/linden/indra/llcommon/llapp.cpp
+++ b/linden/indra/llcommon/llapp.cpp
@@ -49,11 +49,24 @@
49LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop); 49LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);
50BOOL ConsoleCtrlHandler(DWORD fdwCtrlType); 50BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
51#else 51#else
52#include <unistd.h> // for fork() 52# include <signal.h>
53# include <unistd.h> // for fork()
53void setup_signals(); 54void setup_signals();
54void default_unix_signal_handler(int signum, siginfo_t *info, void *); 55void default_unix_signal_handler(int signum, siginfo_t *info, void *);
55const S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; 56# if LL_DARWIN
56#endif 57/* OSX doesn't support SIGRT* */
58S32 LL_SMACKDOWN_SIGNAL = SIGUSR1;
59S32 LL_HEARTBEAT_SIGNAL = SIGUSR2;
60# else
61/* We want reliable delivery of our signals - SIGRT* is it. */
62/* Old LinuxThreads versions eat SIGRTMIN+0 to SIGRTMIN+2, avoid those. */
63/* Note that SIGRTMIN/SIGRTMAX may expand to a glibc function call with a
64 nonconstant result so these are not consts and cannot be used in constant-
65 expressions. SIGRTMAX may return -1 on rare broken setups. */
66S32 LL_SMACKDOWN_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-1) : SIGUSR1;
67S32 LL_HEARTBEAT_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-0) : SIGUSR2;
68# endif // LL_DARWIN
69#endif // LL_WINDOWS
57 70
58// the static application instance 71// the static application instance
59LLApp* LLApp::sApplication = NULL; 72LLApp* LLApp::sApplication = NULL;
@@ -523,6 +536,9 @@ void setup_signals()
523 sigaction(SIGSEGV, &act, NULL); 536 sigaction(SIGSEGV, &act, NULL);
524 sigaction(SIGSYS, &act, NULL); 537 sigaction(SIGSYS, &act, NULL);
525 538
539 sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
540 sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
541
526 // Asynchronous signals that are normally ignored 542 // Asynchronous signals that are normally ignored
527 sigaction(SIGCHLD, &act, NULL); 543 sigaction(SIGCHLD, &act, NULL);
528 sigaction(SIGUSR2, &act, NULL); 544 sigaction(SIGUSR2, &act, NULL);
@@ -533,7 +549,6 @@ void setup_signals()
533 sigaction(SIGINT, &act, NULL); 549 sigaction(SIGINT, &act, NULL);
534 550
535 // Asynchronous signals that result in core 551 // Asynchronous signals that result in core
536 sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
537 sigaction(SIGQUIT, &act, NULL); 552 sigaction(SIGQUIT, &act, NULL);
538} 553}
539 554
@@ -555,6 +570,9 @@ void clear_signals()
555 sigaction(SIGSEGV, &act, NULL); 570 sigaction(SIGSEGV, &act, NULL);
556 sigaction(SIGSYS, &act, NULL); 571 sigaction(SIGSYS, &act, NULL);
557 572
573 sigaction(LL_HEARTBEAT_SIGNAL, &act, NULL);
574 sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
575
558 // Asynchronous signals that are normally ignored 576 // Asynchronous signals that are normally ignored
559 sigaction(SIGCHLD, &act, NULL); 577 sigaction(SIGCHLD, &act, NULL);
560 578
@@ -565,7 +583,6 @@ void clear_signals()
565 583
566 // Asynchronous signals that result in core 584 // Asynchronous signals that result in core
567 sigaction(SIGUSR2, &act, NULL); 585 sigaction(SIGUSR2, &act, NULL);
568 sigaction(LL_SMACKDOWN_SIGNAL, &act, NULL);
569 sigaction(SIGQUIT, &act, NULL); 586 sigaction(SIGQUIT, &act, NULL);
570} 587}
571 588
@@ -586,16 +603,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
586 603
587 switch (signum) 604 switch (signum)
588 { 605 {
589 case SIGALRM: 606 case SIGCHLD:
590 case SIGPIPE:
591 case SIGUSR2:
592 // We don't care about these signals, ignore them
593 if (LLApp::sLogInSignal)
594 {
595 llinfos << "Signal handler - Ignoring this signal" << llendl;
596 }
597 return;
598 case SIGCHLD:
599 if (LLApp::sLogInSignal) 607 if (LLApp::sLogInSignal)
600 { 608 {
601 llinfos << "Signal handler - Got SIGCHLD from " << info->si_pid << llendl; 609 llinfos << "Signal handler - Got SIGCHLD from " << info->si_pid << llendl;
@@ -624,59 +632,6 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
624 clear_signals(); 632 clear_signals();
625 raise(signum); 633 raise(signum);
626 return; 634 return;
627 case LL_SMACKDOWN_SIGNAL: // Smackdown treated just like any other app termination, for now
628 if (LLApp::sLogInSignal)
629 {
630 llwarns << "Signal handler - Handling smackdown signal!" << llendl;
631 }
632 else
633 {
634 // Don't log anything, even errors - this is because this signal could happen anywhere.
635 LLError::setDefaultLevel(LLError::LEVEL_NONE);
636 }
637
638 // Change the signal that we reraise to SIGABRT, so we generate a core dump.
639 signum = SIGABRT;
640 case SIGBUS:
641 case SIGSEGV:
642 case SIGQUIT:
643 if (LLApp::sLogInSignal)
644 {
645 llwarns << "Signal handler - Handling fatal signal!" << llendl;
646 }
647 if (LLApp::isError())
648 {
649 // Received second fatal signal while handling first, just die right now
650 // Set the signal handlers back to default before handling the signal - this makes the next signal wipe out the app.
651 clear_signals();
652
653 if (LLApp::sLogInSignal)
654 {
655 llwarns << "Signal handler - Got another fatal signal while in the error handler, die now!" << llendl;
656 }
657 raise(signum);
658 return;
659 }
660
661 if (LLApp::sLogInSignal)
662 {
663 llwarns << "Signal handler - Flagging error status and waiting for shutdown" << llendl;
664 }
665 // Flag status to ERROR, so thread_error does its work.
666 LLApp::setError();
667 // Block in the signal handler until somebody says that we're done.
668 while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
669 {
670 ms_sleep(10);
671 }
672
673 if (LLApp::sLogInSignal)
674 {
675 llwarns << "Signal handler - App is stopped, reraising signal" << llendl;
676 }
677 clear_signals();
678 raise(signum);
679 return;
680 case SIGINT: 635 case SIGINT:
681 case SIGHUP: 636 case SIGHUP:
682 case SIGTERM: 637 case SIGTERM:
@@ -697,10 +652,76 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
697 } 652 }
698 LLApp::setQuitting(); 653 LLApp::setQuitting();
699 return; 654 return;
655 case SIGALRM:
656 case SIGPIPE:
657 case SIGUSR2:
700 default: 658 default:
701 if (LLApp::sLogInSignal) 659 if (signum == LL_SMACKDOWN_SIGNAL ||
702 { 660 signum == SIGBUS ||
703 llwarns << "Signal handler - Unhandled signal, ignoring!" << llendl; 661 signum == SIGILL ||
662 signum == SIGFPE ||
663 signum == SIGSEGV ||
664 signum == SIGQUIT)
665 {
666 if (signum == LL_SMACKDOWN_SIGNAL)
667 {
668 // Smackdown treated just like any other app termination, for now
669 if (LLApp::sLogInSignal)
670 {
671 llwarns << "Signal handler - Handling smackdown signal!" << llendl;
672 }
673 else
674 {
675 // Don't log anything, even errors - this is because this signal could happen anywhere.
676 LLError::setDefaultLevel(LLError::LEVEL_NONE);
677 }
678
679 // Change the signal that we reraise to SIGABRT, so we generate a core dump.
680 signum = SIGABRT;
681 }
682
683 if (LLApp::sLogInSignal)
684 {
685 llwarns << "Signal handler - Handling fatal signal!" << llendl;
686 }
687 if (LLApp::isError())
688 {
689 // Received second fatal signal while handling first, just die right now
690 // Set the signal handlers back to default before handling the signal - this makes the next signal wipe out the app.
691 clear_signals();
692
693 if (LLApp::sLogInSignal)
694 {
695 llwarns << "Signal handler - Got another fatal signal while in the error handler, die now!" << llendl;
696 }
697 raise(signum);
698 return;
699 }
700
701 if (LLApp::sLogInSignal)
702 {
703 llwarns << "Signal handler - Flagging error status and waiting for shutdown" << llendl;
704 }
705 // Flag status to ERROR, so thread_error does its work.
706 LLApp::setError();
707 // Block in the signal handler until somebody says that we're done.
708 while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
709 {
710 ms_sleep(10);
711 }
712
713 if (LLApp::sLogInSignal)
714 {
715 llwarns << "Signal handler - App is stopped, reraising signal" << llendl;
716 }
717 clear_signals();
718 raise(signum);
719 return;
720 } else {
721 if (LLApp::sLogInSignal)
722 {
723 llinfos << "Signal handler - Unhandled signal " << signum << ", ignoring!" << llendl;
724 }
704 } 725 }
705 } 726 }
706} 727}