Allow users to re-initialize glog
[platform/upstream/glog.git] / src / signalhandler.cc
1 // Copyright (c) 2008, Google Inc.
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 Google Inc. 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: Satoru Takabayashi
31 //
32 // Implementation of InstallFailureSignalHandler().
33
34 #include "utilities.h"
35 #include "stacktrace.h"
36 #include "symbolize.h"
37 #include "glog/logging.h"
38
39 #include <signal.h>
40 #include <time.h>
41 #ifdef HAVE_UCONTEXT_H
42 # include <ucontext.h>
43 #endif
44 #ifdef HAVE_SYS_UCONTEXT_H
45 # include <sys/ucontext.h>
46 #endif
47 #include <algorithm>
48
49 _START_GOOGLE_NAMESPACE_
50
51 namespace {
52
53 // We'll install the failure signal handler for these signals.  We could
54 // use strsignal() to get signal names, but we don't use it to avoid
55 // introducing yet another #ifdef complication.
56 //
57 // The list should be synced with the comment in signalhandler.h.
58 const struct {
59   int number;
60   const char *name;
61 } kFailureSignals[] = {
62   { SIGSEGV, "SIGSEGV" },
63   { SIGILL, "SIGILL" },
64   { SIGFPE, "SIGFPE" },
65   { SIGABRT, "SIGABRT" },
66   { SIGBUS, "SIGBUS" },
67   { SIGTERM, "SIGTERM" },
68 };
69
70 // Returns the program counter from signal context, NULL if unknown.
71 void* GetPC(void* ucontext_in_void) {
72 #if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
73   if (ucontext_in_void != NULL) {
74     ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
75     return (void*)context->PC_FROM_UCONTEXT;
76   }
77 #endif
78   return NULL;
79 }
80
81 // The class is used for formatting error messages.  We don't use printf()
82 // as it's not async signal safe.
83 class MinimalFormatter {
84  public:
85   MinimalFormatter(char *buffer, int size)
86       : buffer_(buffer),
87         cursor_(buffer),
88         end_(buffer + size) {
89   }
90
91   // Returns the number of bytes written in the buffer.
92   int num_bytes_written() const { return cursor_ - buffer_; }
93
94   // Appends string from "str" and updates the internal cursor.
95   void AppendString(const char* str) {
96     int i = 0;
97     while (str[i] != '\0' && cursor_ + i < end_) {
98       cursor_[i] = str[i];
99       ++i;
100     }
101     cursor_ += i;
102   }
103
104   // Formats "number" in "radix" and updates the internal cursor.
105   // Lowercase letters are used for 'a' - 'z'.
106   void AppendUint64(uint64 number, int radix) {
107     int i = 0;
108     while (cursor_ + i < end_) {
109       const int tmp = number % radix;
110       number /= radix;
111       cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10);
112       ++i;
113       if (number == 0) {
114         break;
115       }
116     }
117     // Reverse the bytes written.
118     std::reverse(cursor_, cursor_ + i);
119     cursor_ += i;
120   }
121
122   // Formats "number" as hexadecimal number, and updates the internal
123   // cursor.  Padding will be added in front if needed.
124   void AppendHexWithPadding(uint64 number, int width) {
125     char* start = cursor_;
126     AppendString("0x");
127     AppendUint64(number, 16);
128     // Move to right and add padding in front if needed.
129     if (cursor_ < start + width) {
130       const int64 delta = start + width - cursor_;
131       std::copy(start, cursor_, start + delta);
132       std::fill(start, start + delta, ' ');
133       cursor_ = start + width;
134     }
135   }
136
137  private:
138   char *buffer_;
139   char *cursor_;
140   const char * const end_;
141 };
142
143 // Writes the given data with the size to the standard error.
144 void WriteToStderr(const char* data, int size) {
145   if (write(STDERR_FILENO, data, size) < 0) {
146     // Ignore errors.
147   }
148 }
149
150 // The writer function can be changed by InstallFailureWriter().
151 void (*g_failure_writer)(const char* data, int size) = WriteToStderr;
152
153 // Dumps time information.  We don't dump human-readable time information
154 // as localtime() is not guaranteed to be async signal safe.
155 void DumpTimeInfo() {
156   time_t time_in_sec = time(NULL);
157   char buf[256];  // Big enough for time info.
158   MinimalFormatter formatter(buf, sizeof(buf));
159   formatter.AppendString("*** Aborted at ");
160   formatter.AppendUint64(time_in_sec, 10);
161   formatter.AppendString(" (unix time)");
162   formatter.AppendString(" try \"date -d @");
163   formatter.AppendUint64(time_in_sec, 10);
164   formatter.AppendString("\" if you are using GNU date ***\n");
165   g_failure_writer(buf, formatter.num_bytes_written());
166 }
167
168 // Dumps information about the signal to STDERR.
169 void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
170   // Get the signal name.
171   const char* signal_name = NULL;
172   for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
173     if (signal_number == kFailureSignals[i].number) {
174       signal_name = kFailureSignals[i].name;
175     }
176   }
177
178   char buf[256];  // Big enough for signal info.
179   MinimalFormatter formatter(buf, sizeof(buf));
180
181   formatter.AppendString("*** ");
182   if (signal_name) {
183     formatter.AppendString(signal_name);
184   } else {
185     // Use the signal number if the name is unknown.  The signal name
186     // should be known, but just in case.
187     formatter.AppendString("Signal ");
188     formatter.AppendUint64(signal_number, 10);
189   }
190   formatter.AppendString(" (@0x");
191   formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
192   formatter.AppendString(")");
193   formatter.AppendString(" received by PID ");
194   formatter.AppendUint64(getpid(), 10);
195   formatter.AppendString(" (TID 0x");
196   // We assume pthread_t is an integral number or a pointer, rather
197   // than a complex struct.  In some environments, pthread_self()
198   // returns an uint64 but in some other environments pthread_self()
199   // returns a pointer.  Hence we use C-style cast here, rather than
200   // reinterpret/static_cast, to support both types of environments.
201   formatter.AppendUint64((uintptr_t)pthread_self(), 16);
202   formatter.AppendString(") ");
203   // Only linux has the PID of the signal sender in si_pid.
204 #ifdef OS_LINUX
205   formatter.AppendString("from PID ");
206   formatter.AppendUint64(siginfo->si_pid, 10);
207   formatter.AppendString("; ");
208 #endif
209   formatter.AppendString("stack trace: ***\n");
210   g_failure_writer(buf, formatter.num_bytes_written());
211 }
212
213 // Dumps information about the stack frame to STDERR.
214 void DumpStackFrameInfo(const char* prefix, void* pc) {
215   // Get the symbol name.
216   const char *symbol = "(unknown)";
217   char symbolized[1024];  // Big enough for a sane symbol.
218   // Symbolizes the previous address of pc because pc may be in the
219   // next function.
220   if (Symbolize(reinterpret_cast<char *>(pc) - 1,
221                 symbolized, sizeof(symbolized))) {
222     symbol = symbolized;
223   }
224
225   char buf[1024];  // Big enough for stack frame info.
226   MinimalFormatter formatter(buf, sizeof(buf));
227
228   formatter.AppendString(prefix);
229   formatter.AppendString("@ ");
230   const int width = 2 * sizeof(void*) + 2;  // + 2  for "0x".
231   formatter.AppendHexWithPadding(reinterpret_cast<uintptr_t>(pc), width);
232   formatter.AppendString(" ");
233   formatter.AppendString(symbol);
234   formatter.AppendString("\n");
235   g_failure_writer(buf, formatter.num_bytes_written());
236 }
237
238 // Invoke the default signal handler.
239 void InvokeDefaultSignalHandler(int signal_number) {
240   struct sigaction sig_action;
241   memset(&sig_action, 0, sizeof(sig_action));
242   sigemptyset(&sig_action.sa_mask);
243   sig_action.sa_handler = SIG_DFL;
244   sigaction(signal_number, &sig_action, NULL);
245   kill(getpid(), signal_number);
246 }
247
248 // This variable is used for protecting FailureSignalHandler() from
249 // dumping stuff while another thread is doing it.  Our policy is to let
250 // the first thread dump stuff and let other threads wait.
251 // See also comments in FailureSignalHandler().
252 static pthread_t* g_entered_thread_id_pointer = NULL;
253
254 // Dumps signal and stack frame information, and invokes the default
255 // signal handler once our job is done.
256 void FailureSignalHandler(int signal_number,
257                           siginfo_t *signal_info,
258                           void *ucontext) {
259   // First check if we've already entered the function.  We use an atomic
260   // compare and swap operation for platforms that support it.  For other
261   // platforms, we use a naive method that could lead to a subtle race.
262
263   // We assume pthread_self() is async signal safe, though it's not
264   // officially guaranteed.
265   pthread_t my_thread_id = pthread_self();
266   // NOTE: We could simply use pthread_t rather than pthread_t* for this,
267   // if pthread_self() is guaranteed to return non-zero value for thread
268   // ids, but there is no such guarantee.  We need to distinguish if the
269   // old value (value returned from __sync_val_compare_and_swap) is
270   // different from the original value (in this case NULL).
271   pthread_t* old_thread_id_pointer =
272       glog_internal_namespace_::sync_val_compare_and_swap(
273           &g_entered_thread_id_pointer,
274           static_cast<pthread_t*>(NULL),
275           &my_thread_id);
276   if (old_thread_id_pointer != NULL) {
277     // We've already entered the signal handler.  What should we do?
278     if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
279       // It looks the current thread is reentering the signal handler.
280       // Something must be going wrong (maybe we are reentering by another
281       // type of signal?).  Kill ourself by the default signal handler.
282       InvokeDefaultSignalHandler(signal_number);
283     }
284     // Another thread is dumping stuff.  Let's wait until that thread
285     // finishes the job and kills the process.
286     while (true) {
287       sleep(1);
288     }
289   }
290   // This is the first time we enter the signal handler.  We are going to
291   // do some interesting stuff from here.
292   // TODO(satorux): We might want to set timeout here using alarm(), but
293   // mixing alarm() and sleep() can be a bad idea.
294
295   // First dump time info.
296   DumpTimeInfo();
297
298   // Get the program counter from ucontext.
299   void *pc = GetPC(ucontext);
300   DumpStackFrameInfo("PC: ", pc);
301
302 #ifdef HAVE_STACKTRACE
303   // Get the stack traces.
304   void *stack[32];
305   // +1 to exclude this function.
306   const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
307   DumpSignalInfo(signal_number, signal_info);
308   // Dump the stack traces.
309   for (int i = 0; i < depth; ++i) {
310     DumpStackFrameInfo("    ", stack[i]);
311   }
312 #endif
313
314   // *** TRANSITION ***
315   //
316   // BEFORE this point, all code must be async-termination-safe!
317   // (See WARNING above.)
318   //
319   // AFTER this point, we do unsafe things, like using LOG()!
320   // The process could be terminated or hung at any time.  We try to
321   // do more useful things first and riskier things later.
322
323   // Flush the logs before we do anything in case 'anything'
324   // causes problems.
325   FlushLogFilesUnsafe(0);
326
327   // Kill ourself by the default signal handler.
328   InvokeDefaultSignalHandler(signal_number);
329 }
330
331 }  // namespace
332
333 void InstallFailureSignalHandler() {
334   // Build the sigaction struct.
335   struct sigaction sig_action;
336   memset(&sig_action, 0, sizeof(sig_action));
337   sigemptyset(&sig_action.sa_mask);
338   sig_action.sa_flags |= SA_SIGINFO;
339   sig_action.sa_sigaction = &FailureSignalHandler;
340
341   for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
342     CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
343   }
344 }
345
346 void InstallFailureWriter(void (*writer)(const char* data, int size)) {
347   g_failure_writer = writer;
348 }
349
350 _END_GOOGLE_NAMESPACE_