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