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 <utils/String8.h>
24 #include <utils/Vector.h>
25 
26 #include <stdint.h>
27 #include <sys/types.h>
28 
29 #if !defined(__APPLE__) && !defined(_WIN32)
30 # define WEAKS_AVAILABLE 1
31 #endif
32 #ifndef CALLSTACK_WEAK
33 # ifdef WEAKS_AVAILABLE
34 #   define CALLSTACK_WEAK __attribute__((weak))
35 # else // !WEAKS_AVAILABLE
36 #   define CALLSTACK_WEAK
37 # endif // !WEAKS_AVAILABLE
38 #endif // CALLSTACK_WEAK predefined
39 
40 #define ALWAYS_INLINE __attribute__((always_inline))
41 
42 namespace android {
43 
44 class Printer;
45 
46 // Collect/print the call stack (function, file, line) traces for a single thread.
47 class CallStack {
48 public:
49     // Create an empty call stack. No-op.
50     CallStack();
51     // Create a callstack with the current thread's stack trace.
52     // Immediately dump it to logcat using the given logtag.
53     CallStack(const char* logtag, int32_t ignoreDepth = 1);
54     ~CallStack();
55 
56     // Reset the stack frames (same as creating an empty call stack).
clear()57     void clear() { mFrameLines.clear(); }
58 
59     // Immediately collect the stack traces for the specified thread.
60     // The default is to dump the stack of the current call.
61     void update(int32_t ignoreDepth = 1, pid_t tid = -1);
62 
63     // Dump a stack trace to the log using the supplied logtag.
64     void log(const char* logtag,
65              android_LogPriority priority = ANDROID_LOG_DEBUG,
66              const char* prefix = nullptr) const;
67 
68     // Dump a stack trace to the specified file descriptor.
69     void dump(int fd, int indent = 0, const char* prefix = nullptr) const;
70 
71     // Return a string (possibly very long) containing the complete stack trace.
72     String8 toString(const char* prefix = nullptr) const;
73 
74     // Dump a serialized representation of the stack trace to the specified printer.
75     void print(Printer& printer) const;
76 
77     // Get the count of stack frames that are in this call stack.
size()78     size_t size() const { return mFrameLines.size(); }
79 
80     // DO NOT USE ANYTHING BELOW HERE. The following public members are expected
81     // to disappear again shortly, once a better replacement facility exists.
82     // The replacement facility will be incompatible!
83 
84     // Debugging accesses to some basic functionality. These use weak symbols to
85     // avoid introducing a dependency on libutilscallstack. Such a dependency from
86     // libutils results in a cyclic build dependency. These routines can be called
87     // from within libutils. But if the actual library is unavailable, they do
88     // nothing.
89     //
90     // DO NOT USE THESE. They will disappear.
91     struct StackDeleter {
92 #ifdef WEAKS_AVAILABLE
operatorStackDeleter93         void operator()(CallStack* stack) {
94             deleteStack(stack);
95         }
96 #else
97         void operator()(CallStack*) {}
98 #endif
99     };
100 
101     typedef std::unique_ptr<CallStack, StackDeleter> CallStackUPtr;
102 
103     // Return current call stack if possible, nullptr otherwise.
104 #ifdef WEAKS_AVAILABLE
105     static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t ignoreDepth = 1) {
106         if (reinterpret_cast<uintptr_t>(getCurrentInternal) == 0) {
107             ALOGW("CallStack::getCurrentInternal not linked, returning null");
108             return CallStackUPtr(nullptr);
109         } else {
110             return getCurrentInternal(ignoreDepth);
111         }
112     }
113 #else // !WEAKS_AVAILABLE
114     static CallStackUPtr ALWAYS_INLINE getCurrent(int32_t = 1) {
115         return CallStackUPtr(nullptr);
116     }
117 #endif // !WEAKS_AVAILABLE
118 
119 #ifdef WEAKS_AVAILABLE
120     static void ALWAYS_INLINE logStack(const char* logtag, CallStack* stack = getCurrent().get(),
121                                        android_LogPriority priority = ANDROID_LOG_DEBUG) {
122         if (reinterpret_cast<uintptr_t>(logStackInternal) != 0 && stack != nullptr) {
123             logStackInternal(logtag, stack, priority);
124         } else {
125             ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
126         }
127     }
128 
129 #else
130     static void ALWAYS_INLINE logStack(const char* logtag, CallStack* = getCurrent().get(),
131                                        android_LogPriority = ANDROID_LOG_DEBUG) {
132         ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
133     }
134 #endif // !WEAKS_AVAILABLE
135 
136 #ifdef WEAKS_AVAILABLE
137     static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
138                                                const CallStack* stack = getCurrent().get()) {
139         if (reinterpret_cast<uintptr_t>(stackToStringInternal) != 0 && stack != nullptr) {
140             return stackToStringInternal(prefix, stack);
141         } else {
142             return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
143         }
144     }
145 #else // !WEAKS_AVAILABLE
146     static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
147                                                const CallStack* = getCurrent().get()) {
148         return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
149     }
150 #endif // !WEAKS_AVAILABLE
151 
152   private:
153 #ifdef WEAKS_AVAILABLE
154     static CallStackUPtr CALLSTACK_WEAK getCurrentInternal(int32_t ignoreDepth);
155     static void CALLSTACK_WEAK logStackInternal(const char* logtag, const CallStack* stack,
156                                                 android_LogPriority priority);
157     static String8 CALLSTACK_WEAK stackToStringInternal(const char* prefix, const CallStack* stack);
158     // The deleter is only invoked on non-null pointers. Hence it will never be
159     // invoked if CallStack is not linked.
160     static void CALLSTACK_WEAK deleteStack(CallStack* stack);
161 #endif // WEAKS_AVAILABLE
162 
163     Vector<String8> mFrameLines;
164 };
165 
166 }  // namespace android
167 
168 #endif // ANDROID_CALLSTACK_H
169