• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_CALLSTACK_H
18 #define ANDROID_CALLSTACK_H
19 
20 #include <memory>
21 
22 #include <android/log.h>
23 #include <backtrace/backtrace_constants.h>
24 #include <utils/String8.h>
25 #include <utils/Vector.h>
26 
27 #include <stdint.h>
28 #include <sys/types.h>
29 
30 #if !defined(__APPLE__) && !defined(_WIN32)
31 # define WEAKS_AVAILABLE 1
32 #endif
33 #ifndef CALLSTACK_WEAK
34 # ifdef WEAKS_AVAILABLE
35 #   define CALLSTACK_WEAK __attribute__((weak))
36 # else // !WEAKS_AVAILABLE
37 #   define CALLSTACK_WEAK
38 # endif // !WEAKS_AVAILABLE
39 #endif // CALLSTACK_WEAK predefined
40 
41 #define ALWAYS_INLINE __attribute__((always_inline))
42 
43 namespace android {
44 
45 class Printer;
46 
47 // Collect/print the call stack (function, file, line) traces for a single thread.
48 class CallStack {
49 public:
50     // Create an empty call stack. No-op.
51     CallStack();
52     // Create a callstack with the current thread's stack trace.
53     // Immediately dump it to logcat using the given logtag.
54     CallStack(const char* logtag, int32_t ignoreDepth = 1);
55     ~CallStack();
56 
57     // Reset the stack frames (same as creating an empty call stack).
clear()58     void clear() { mFrameLines.clear(); }
59 
60     // Immediately collect the stack traces for the specified thread.
61     // The default is to dump the stack of the current call.
62     void update(int32_t ignoreDepth = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);
63 
64     // Dump a stack trace to the log using the supplied logtag.
65     void log(const char* logtag,
66              android_LogPriority priority = ANDROID_LOG_DEBUG,
67              const char* prefix = nullptr) const;
68 
69     // Dump a stack trace to the specified file descriptor.
70     void dump(int fd, int indent = 0, const char* prefix = nullptr) const;
71 
72     // Return a string (possibly very long) containing the complete stack trace.
73     String8 toString(const char* prefix = nullptr) const;
74 
75     // Dump a serialized representation of the stack trace to the specified printer.
76     void print(Printer& printer) const;
77 
78     // Get the count of stack frames that are in this call stack.
size()79     size_t size() const { return mFrameLines.size(); }
80 
81     // DO NOT USE ANYTHING BELOW HERE. The following public members are expected
82     // to disappear again shortly, once a better replacement facility exists.
83     // The replacement facility will be incompatible!
84 
85     // Debugging accesses to some basic functionality. These use weak symbols to
86     // avoid introducing a dependency on libutilscallstack. Such a dependency from
87     // libutils results in a cyclic build dependency. These routines can be called
88     // from within libutils. But if the actual library is unavailable, they do
89     // nothing.
90     //
91     // DO NOT USE THESE. They will disappear.
92     struct StackDeleter {
93 #ifdef WEAKS_AVAILABLE
operatorStackDeleter94         void operator()(CallStack* stack) {
95             deleteStack(stack);
96         }
97 #else
98         void operator()(CallStack*) {}
99 #endif
100     };
101 
102     typedef std::unique_ptr<CallStack, StackDeleter> CallStackUPtr;
103 
104     // Return current call stack if possible, nullptr otherwise.
105 #ifdef WEAKS_AVAILABLE
106     static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t ignoreDepth = 1) {
107         if (reinterpret_cast<uintptr_t>(getCurrentInternal) == 0) {
108             ALOGW("CallStack::getCurrentInternal not linked, returning null");
109             return CallStackUPtr(nullptr);
110         } else {
111             return getCurrentInternal(ignoreDepth);
112         }
113     }
114 #else // !WEAKS_AVAILABLE
115     static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t = 1) {
116         return CallStackUPtr(nullptr);
117     }
118 #endif // !WEAKS_AVAILABLE
119 
120 #ifdef WEAKS_AVAILABLE
121     static void ALWAYS_INLINE logStack(const char* logtag, CallStack* stack = getCurrent().get(),
122                                        android_LogPriority priority = ANDROID_LOG_DEBUG) {
123         if (reinterpret_cast<uintptr_t>(logStackInternal) != 0 && stack != nullptr) {
124             logStackInternal(logtag, stack, priority);
125         } else {
126             ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
127         }
128     }
129 
130 #else
131     static void ALWAYS_INLINE logStack(const char* logtag, CallStack* = getCurrent().get(),
132                                        android_LogPriority = ANDROID_LOG_DEBUG) {
133         ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
134     }
135 #endif // !WEAKS_AVAILABLE
136 
137 #ifdef WEAKS_AVAILABLE
138     static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
139                                                const CallStack* stack = getCurrent().get()) {
140         if (reinterpret_cast<uintptr_t>(stackToStringInternal) != 0 && stack != nullptr) {
141             return stackToStringInternal(prefix, stack);
142         } else {
143             return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
144         }
145     }
146 #else // !WEAKS_AVAILABLE
147     static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
148                                                const CallStack* = getCurrent().get()) {
149         return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
150     }
151 #endif // !WEAKS_AVAILABLE
152 
153   private:
154 #ifdef WEAKS_AVAILABLE
155     static CallStackUPtr CALLSTACK_WEAK getCurrentInternal(int32_t ignoreDepth);
156     static void CALLSTACK_WEAK logStackInternal(const char* logtag, const CallStack* stack,
157                                                 android_LogPriority priority);
158     static String8 CALLSTACK_WEAK stackToStringInternal(const char* prefix, const CallStack* stack);
159     // The deleter is only invoked on non-null pointers. Hence it will never be
160     // invoked if CallStack is not linked.
161     static void CALLSTACK_WEAK deleteStack(CallStack* stack);
162 #endif // WEAKS_AVAILABLE
163 
164     Vector<String8> mFrameLines;
165 };
166 
167 }  // namespace android
168 
169 #endif // ANDROID_CALLSTACK_H
170