blob: 7a4a345d05a609da72ca62d18108d15ef7febd47 [file] [log] [blame]
The Android Open Source Projectcbb10112009-03-03 19:31:44 -08001/*
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
Hans Boehm2a019ec2018-08-07 23:45:25 +000020#include <memory>
21
Igor Murashkinec79ef22013-10-24 17:09:15 -070022#include <android/log.h>
Christopher Ferris46756822014-01-14 20:16:30 -080023#include <backtrace/backtrace_constants.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080024#include <utils/String8.h>
Christopher Ferris038ac692013-10-31 16:25:04 -070025#include <utils/Vector.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080026
Igor Murashkinec79ef22013-10-24 17:09:15 -070027#include <stdint.h>
28#include <sys/types.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080029
Hans Boehm2a019ec2018-08-07 23:45:25 +000030#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
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080043namespace android {
44
Igor Murashkinec79ef22013-10-24 17:09:15 -070045class Printer;
46
47// Collect/print the call stack (function, file, line) traces for a single thread.
48class CallStack {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080049public:
Igor Murashkinec79ef22013-10-24 17:09:15 -070050 // Create an empty call stack. No-op.
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080051 CallStack();
Igor Murashkinec79ef22013-10-24 17:09:15 -070052 // Create a callstack with the current thread's stack trace.
53 // Immediately dump it to logcat using the given logtag.
Hans Boehm2a019ec2018-08-07 23:45:25 +000054 CallStack(const char* logtag, int32_t ignoreDepth = 1);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080055 ~CallStack();
56
Igor Murashkinec79ef22013-10-24 17:09:15 -070057 // Reset the stack frames (same as creating an empty call stack).
Christopher Ferris038ac692013-10-31 16:25:04 -070058 void clear() { mFrameLines.clear(); }
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080059
Igor Murashkinec79ef22013-10-24 17:09:15 -070060 // Immediately collect the stack traces for the specified thread.
Christopher Ferris038ac692013-10-31 16:25:04 -070061 // The default is to dump the stack of the current call.
Hans Boehm2a019ec2018-08-07 23:45:25 +000062 void update(int32_t ignoreDepth = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080063
Igor Murashkinec79ef22013-10-24 17:09:15 -070064 // Dump a stack trace to the log using the supplied logtag.
65 void log(const char* logtag,
66 android_LogPriority priority = ANDROID_LOG_DEBUG,
Yi Kongc1a15622018-07-11 17:37:34 -070067 const char* prefix = nullptr) const;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080068
Igor Murashkinec79ef22013-10-24 17:09:15 -070069 // Dump a stack trace to the specified file descriptor.
Yi Kongc1a15622018-07-11 17:37:34 -070070 void dump(int fd, int indent = 0, const char* prefix = nullptr) const;
Igor Murashkinec79ef22013-10-24 17:09:15 -070071
72 // Return a string (possibly very long) containing the complete stack trace.
Yi Kongc1a15622018-07-11 17:37:34 -070073 String8 toString(const char* prefix = nullptr) const;
Igor Murashkinec79ef22013-10-24 17:09:15 -070074
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.
Christopher Ferris038ac692013-10-31 16:25:04 -070079 size_t size() const { return mFrameLines.size(); }
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080080
Hans Boehm2a019ec2018-08-07 23:45:25 +000081 // 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
94 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 {
Steven Moreland83380722019-01-02 18:29:28 -0800126 ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
Hans Boehm2a019ec2018-08-07 23:45:25 +0000127 }
128 }
129
130#else
Steven Moreland83380722019-01-02 18:29:28 -0800131 static void ALWAYS_INLINE logStack(const char* logtag, CallStack* = getCurrent().get(),
Hans Boehm2a019ec2018-08-07 23:45:25 +0000132 android_LogPriority = ANDROID_LOG_DEBUG) {
Steven Moreland83380722019-01-02 18:29:28 -0800133 ALOG(LOG_WARN, logtag, "CallStack::logStackInternal not linked");
Hans Boehm2a019ec2018-08-07 23:45:25 +0000134 }
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 {
Steven Moreland83380722019-01-02 18:29:28 -0800143 return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
Hans Boehm2a019ec2018-08-07 23:45:25 +0000144 }
145 }
146#else // !WEAKS_AVAILABLE
Steven Moreland83380722019-01-02 18:29:28 -0800147 static String8 ALWAYS_INLINE stackToString(const char* prefix = nullptr,
Hans Boehm2a019ec2018-08-07 23:45:25 +0000148 const CallStack* = getCurrent().get()) {
Steven Moreland83380722019-01-02 18:29:28 -0800149 return String8::format("%s<CallStack package not linked>", (prefix ? prefix : ""));
Hans Boehm2a019ec2018-08-07 23:45:25 +0000150 }
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
Christopher Ferris038ac692013-10-31 16:25:04 -0700164 Vector<String8> mFrameLines;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800165};
166
Pirama Arumuga Nainar90affce2018-04-11 23:10:28 -0700167} // namespace android
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800168
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800169#endif // ANDROID_CALLSTACK_H