Initialize gflags in signalhandler_unittest.
[platform/upstream/glog.git] / src / stacktrace_x86_64-inl.h
1 // Copyright 2005 - 2007 Google Inc.
2 // All rights reserved.
3 //
4 // Author: Arun Sharma
5 //
6 // Produce stack trace using libgcc
7
8 extern "C" {
9 #include <stdlib.h> // for NULL
10 #include <unwind.h> // ABI defined unwinder
11 }
12 #include "stacktrace.h"
13
14 _START_GOOGLE_NAMESPACE_
15
16 typedef struct {
17   void **result;
18   int max_depth;
19   int skip_count;
20   int count;
21 } trace_arg_t;
22
23
24 // Workaround for the malloc() in _Unwind_Backtrace() issue.
25 static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {
26   return _URC_NO_REASON;
27 }
28
29
30 // This code is not considered ready to run until
31 // static initializers run so that we are guaranteed
32 // that any malloc-related initialization is done.
33 static bool ready_to_run = false;
34 class StackTraceInit {
35  public:
36    StackTraceInit() {
37      // Extra call to force initialization
38      _Unwind_Backtrace(nop_backtrace, NULL);
39      ready_to_run = true;
40    }
41 };
42
43 static StackTraceInit module_initializer;  // Force initialization
44
45 static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
46   trace_arg_t *targ = (trace_arg_t *) opq;
47
48   if (targ->skip_count > 0) {
49     targ->skip_count--;
50   } else {
51     targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
52   }
53
54   if (targ->count == targ->max_depth)
55     return _URC_END_OF_STACK;
56
57   return _URC_NO_REASON;
58 }
59
60 // If you change this function, also change GetStackFrames below.
61 int GetStackTrace(void** result, int max_depth, int skip_count) {
62   if (!ready_to_run)
63     return 0;
64
65   trace_arg_t targ;
66
67   skip_count += 1;         // Do not include the "GetStackTrace" frame
68
69   targ.result = result;
70   targ.max_depth = max_depth;
71   targ.skip_count = skip_count;
72   targ.count = 0;
73
74   _Unwind_Backtrace(GetOneFrame, &targ);
75
76   return targ.count;
77 }
78
79 _END_GOOGLE_NAMESPACE_