diff options
Diffstat (limited to 'linden/indra/llcommon/llapp.cpp')
-rw-r--r-- | linden/indra/llcommon/llapp.cpp | 163 |
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 @@ | |||
49 | LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop); | 49 | LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop); |
50 | BOOL ConsoleCtrlHandler(DWORD fdwCtrlType); | 50 | BOOL ConsoleCtrlHandler(DWORD fdwCtrlType); |
51 | #else | 51 | #else |
52 | #include <unistd.h> // for fork() | 52 | # include <signal.h> |
53 | # include <unistd.h> // for fork() | ||
53 | void setup_signals(); | 54 | void setup_signals(); |
54 | void default_unix_signal_handler(int signum, siginfo_t *info, void *); | 55 | void default_unix_signal_handler(int signum, siginfo_t *info, void *); |
55 | const S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; | 56 | # if LL_DARWIN |
56 | #endif | 57 | /* OSX doesn't support SIGRT* */ |
58 | S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; | ||
59 | S32 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. */ | ||
66 | S32 LL_SMACKDOWN_SIGNAL = (SIGRTMAX >= 0) ? (SIGRTMAX-1) : SIGUSR1; | ||
67 | S32 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 |
59 | LLApp* LLApp::sApplication = NULL; | 72 | LLApp* 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 | } |