• 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 #pragma once
18 
19 #include <memory>
20 
21 #include <android/log.h>
22 #include <utils/String8.h>
23 #include <utils/Vector.h>
24 
25 #include <stdint.h>
26 #include <sys/types.h>
27 
28 #if !defined(__APPLE__) && !defined(_WIN32)
29 # define CALLSTACK_WEAKS_AVAILABLE 1
30 #endif
31 #ifndef CALLSTACK_WEAK
32 # ifdef CALLSTACK_WEAKS_AVAILABLE
33 #   define CALLSTACK_WEAK __attribute__((weak))
34 # else // !CALLSTACK_WEAKS_AVAILABLE
35 #   define CALLSTACK_WEAK
36 # endif // !CALLSTACK_WEAKS_AVAILABLE
37 #endif // CALLSTACK_WEAK predefined
38 
39 #ifndef CALLSTACK_ALWAYS_INLINE
40 #define CALLSTACK_ALWAYS_INLINE __attribute__((always_inline))
41 #endif  // CALLSTACK_ALWAYS_INLINE predefined
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 = -1);
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 CALLSTACK_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 CALLSTACK_WEAKS_AVAILABLE
106     static CallStackUPtr CALLSTACK_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 // !CALLSTACK_WEAKS_AVAILABLE
115     static CallStackUPtr CALLSTACK_ALWAYS_INLINE getCurrent(int32_t = 1) {
116         return CallStackUPtr(nullptr);
117     }
118 #endif // !CALLSTACK_WEAKS_AVAILABLE
119 
120 #ifdef CALLSTACK_WEAKS_AVAILABLE
121     static void CALLSTACK_ALWAYS_INLINE logStack(const char* logtag,
122                                                  CallStack* stack = getCurrent().get(),
123                                                  android_LogPriority priority = ANDROID_LOG_DEBUG) {
124         if (reinterpret_cast<uintptr_t>(logStackInternal) != 0 && stack != nullptr) {
125             logStackInternal(logtag, stack, priority);
126         } else {
127             ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
128         }
129     }
130 
131 #else
132     static void CALLSTACK_ALWAYS_INLINE logStack(const char* logtag,
133                                                  CallStack* = getCurrent().get(),
134                                                  android_LogPriority = ANDROID_LOG_DEBUG) {
135         ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
136     }
137 #endif // !CALLSTACK_WEAKS_AVAILABLE
138 
139 #ifdef CALLSTACK_WEAKS_AVAILABLE
140     static String8 CALLSTACK_ALWAYS_INLINE
141     stackToString(const char* prefix = nullptr, const CallStack* stack = getCurrent().get()) {
142         if (reinterpret_cast<uintptr_t>(stackToStringInternal) != 0 && stack != nullptr) {
143             return stackToStringInternal(prefix, stack);
144         } else {
145             return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
146         }
147     }
148 #else // !CALLSTACK_WEAKS_AVAILABLE
149     static String8 CALLSTACK_ALWAYS_INLINE stackToString(const char* prefix = nullptr,
150                                                          const CallStack* = getCurrent().get()) {
151         return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
152     }
153 #endif // !CALLSTACK_WEAKS_AVAILABLE
154 
155   private:
156 #ifdef CALLSTACK_WEAKS_AVAILABLE
157     static CallStackUPtr CALLSTACK_WEAK getCurrentInternal(int32_t ignoreDepth);
158     static void CALLSTACK_WEAK logStackInternal(const char* logtag, const CallStack* stack,
159                                                 android_LogPriority priority);
160     static String8 CALLSTACK_WEAK stackToStringInternal(const char* prefix, const CallStack* stack);
161     // The deleter is only invoked on non-null pointers. Hence it will never be
162     // invoked if CallStack is not linked.
163     static void CALLSTACK_WEAK deleteStack(CallStack* stack);
164 #endif // CALLSTACK_WEAKS_AVAILABLE
165 
166     Vector<String8> mFrameLines;
167 };
168 
169 }  // namespace android
170 
171 #undef CALLSTACK_WEAKS_AVAILABLE
172 #undef CALLSTACK_WEAK
173 #undef CALLSTACK_ALWAYS_INLINE
174