root/trunk/whisperlib/common/base/signal_handlers.cc

Revision 7, 4.7 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2009, Whispersoft s.r.l.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Whispersoft s.r.l. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Cosmin Tudorache
31
32 #include <string.h>
33 #include <unistd.h>
34 #include <signal.h>
35 #include <execinfo.h>
36 #include "common/base/log.h"
37 #include "common/base/errno.h"
38 #include "common/base/system.h"
39 #include "common/base/date.h"
40 #include "common/base/callback.h"
41
42 extern void bt_signal(int sig, const char* program_name);
43
44 namespace common {
45
46 bool g_hang_on_signal_stack_trace = false;
47 // true if the application is already hanging
48 bool g_application_is_hanging = false;
49
50 void HandleSignalStackTrace(int signum,
51                             siginfo_t* info,
52                             void* context) {
53   // TODO(cpopescu) : Disable this for now, anyway we keep it in mind..
54   // if ( signum == SIGRTMIN ) {
55   //   if ( info != NULL && info->si_value.sival_ptr != NULL ) {
56   //     Closure* const closure =
57   //         reinterpret_cast<Closure*>(info->si_value.sival_ptr);
58   //     closure->Run();
59   //   }
60   //   return;
61   // }
62
63   string backtrace(common::GetBacktrace());
64
65   // [COSMIN] Not goot to use LOG functions. If the initial exception
66   //          happened inside a LOG statement, then using LOG here would
67   //          recursively generate a new exception.
68   cerr << "\033[31m On [" << timer::Date() << " ("
69        << timer::Date(true) << ")]\n"
70        << " Signal cought " << signum
71        << " - " << strsignal(signum) << endl
72        << backtrace << "\033[0m\n";
73
74   if ( g_hang_on_signal_stack_trace ) {
75     g_application_is_hanging = true;
76     while ( true ) {
77       cerr << "Program pid=" << getpid() << " tid="
78            << static_cast<uint32>(pthread_self())
79            << " is hanging now. You can Debug it or Kill (Ctrl+C) it."
80            << endl;
81       ::sleep(30);
82     }
83   }
84   common::Exit(-1, true);
85 }
86
87 bool InstallDefaultSignalHandlers(bool hang_on_bad_signals) {
88   g_hang_on_signal_stack_trace = hang_on_bad_signals;
89
90   // install signal handler routines
91   struct sigaction sa;
92   sa.sa_handler = NULL;
93   sa.sa_sigaction = HandleSignalStackTrace;
94   sigemptyset(&sa.sa_mask);
95   //  Restart functions if interrupted by handler
96   //  We want to process RT signals..
97   sa.sa_flags = SA_RESTART | SA_SIGINFO;
98
99   if ( -1 == ::sigaction(SIGABRT, &sa, NULL) ||   // assert failed
100        -1 == ::sigaction(SIGBUS, &sa, NULL) ||
101        -1 == ::sigaction(SIGHUP, &sa, NULL) ||
102        -1 == ::sigaction(SIGTERM, &sa, NULL) ||
103        -1 == ::sigaction(SIGFPE, &sa, NULL) ||
104        -1 == ::sigaction(SIGILL, &sa, NULL) ||
105        -1 == ::sigaction(SIGSEGV, &sa, NULL) ) {
106     LOG_ERROR << "cannot install SIGNAL-handler: "
107               << GetLastSystemErrorDescription();
108     return false;
109   }
110   // TODO(cpopescu): disable this for now
111   //     CHECK(!::sigaction(SIGRTMIN, &sa, NULL));
112
113   // TODO(cosmin): ignore SIGPIPE.
114   //               Writing to a disconnected socket causes SIGPIPE.
115   //               All system calls that would cause SIGPIPE to be sent will
116   //               return -1 and set errno to EPIPE.
117   if ( SIG_ERR == ::signal(SIGPIPE, SIG_IGN) ) {
118     LOG_ERROR << "cannot install SIGNAL-handler: "
119               << GetLastSystemErrorDescription();
120     return false;
121   }
122
123   return true;
124 }
125
126 bool IsApplicationHanging() {
127   return g_application_is_hanging;
128 }
129 }
Note: See TracBrowser for help on using the browser.