blob: 4ceaa7c912e24c5573f9fcf4e0016bec5e9dabbe [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#define LOG_TAG "CallStack"
18
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080019#include <utils/CallStack.h>
Igor Murashkinec79ef22013-10-24 17:09:15 -070020#include <utils/Printer.h>
21#include <utils/Errors.h>
22#include <utils/Log.h>
Jeff Brownea45b012011-10-19 20:32:43 -070023#include <corkscrew/backtrace.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080024
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080025namespace android {
26
Jeff Brownea45b012011-10-19 20:32:43 -070027CallStack::CallStack() :
28 mCount(0) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080029}
30
Mathias Agopiand34a8ca2013-03-21 17:12:40 -070031CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
Igor Murashkinec79ef22013-10-24 17:09:15 -070032 this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD);
33 this->log(logtag);
Mathias Agopiand34a8ca2013-03-21 17:12:40 -070034}
35
Jeff Brownea45b012011-10-19 20:32:43 -070036CallStack::CallStack(const CallStack& rhs) :
37 mCount(rhs.mCount) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080038 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070039 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080040 }
41}
42
Jeff Brownea45b012011-10-19 20:32:43 -070043CallStack::~CallStack() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080044}
45
Jeff Brownea45b012011-10-19 20:32:43 -070046CallStack& CallStack::operator = (const CallStack& rhs) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080047 mCount = rhs.mCount;
48 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070049 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080050 }
51 return *this;
52}
53
54bool CallStack::operator == (const CallStack& rhs) const {
55 if (mCount != rhs.mCount)
56 return false;
Jeff Brownea45b012011-10-19 20:32:43 -070057 return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080058}
59
60bool CallStack::operator != (const CallStack& rhs) const {
61 return !operator == (rhs);
62}
63
64bool CallStack::operator < (const CallStack& rhs) const {
65 if (mCount != rhs.mCount)
66 return mCount < rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070067 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080068}
69
70bool CallStack::operator >= (const CallStack& rhs) const {
71 return !operator < (rhs);
72}
73
74bool CallStack::operator > (const CallStack& rhs) const {
75 if (mCount != rhs.mCount)
76 return mCount > rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070077 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080078}
79
80bool CallStack::operator <= (const CallStack& rhs) const {
81 return !operator > (rhs);
82}
83
84const void* CallStack::operator [] (int index) const {
85 if (index >= int(mCount))
86 return 0;
Jeff Brownea45b012011-10-19 20:32:43 -070087 return reinterpret_cast<const void*>(mStack[index].absolute_pc);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080088}
89
Jeff Brownea45b012011-10-19 20:32:43 -070090void CallStack::clear() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080091 mCount = 0;
92}
93
Igor Murashkinec79ef22013-10-24 17:09:15 -070094void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) {
Jeff Brownea45b012011-10-19 20:32:43 -070095 if (maxDepth > MAX_DEPTH) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080096 maxDepth = MAX_DEPTH;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080097 }
Igor Murashkinec79ef22013-10-24 17:09:15 -070098 ssize_t count;
99
100 if (tid >= 0) {
101 count = unwind_backtrace_thread(tid, mStack, ignoreDepth + 1, maxDepth);
102 } else if (tid == CURRENT_THREAD) {
103 count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
104 } else {
105 ALOGE("%s: Invalid tid specified (%d)", __FUNCTION__, tid);
106 count = 0;
107 }
108
Jeff Brownea45b012011-10-19 20:32:43 -0700109 mCount = count > 0 ? count : 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800110}
111
Igor Murashkinec79ef22013-10-24 17:09:15 -0700112void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
113 LogPrinter printer(logtag, priority, prefix, /*ignoreBlankLines*/false);
114 print(printer);
115}
Jeff Brownea45b012011-10-19 20:32:43 -0700116
Igor Murashkinec79ef22013-10-24 17:09:15 -0700117void CallStack::dump(int fd, int indent, const char* prefix) const {
118 FdPrinter printer(fd, indent, prefix);
119 print(printer);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800120}
121
Jeff Brownea45b012011-10-19 20:32:43 -0700122String8 CallStack::toString(const char* prefix) const {
123 String8 str;
Igor Murashkinec79ef22013-10-24 17:09:15 -0700124
125 String8Printer printer(&str, prefix);
126 print(printer);
127
128 return str;
129}
130
131void CallStack::print(Printer& printer) const {
Jeff Brownea45b012011-10-19 20:32:43 -0700132 backtrace_symbol_t symbols[mCount];
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800133
Jeff Brownea45b012011-10-19 20:32:43 -0700134 get_backtrace_symbols(mStack, mCount, symbols);
135 for (size_t i = 0; i < mCount; i++) {
Jeff Brown11189f52011-11-21 21:04:55 -0800136 char line[MAX_BACKTRACE_LINE_LENGTH];
137 format_backtrace_line(i, &mStack[i], &symbols[i],
138 line, MAX_BACKTRACE_LINE_LENGTH);
Igor Murashkinec79ef22013-10-24 17:09:15 -0700139 printer.printLine(line);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800140 }
Jeff Brownea45b012011-10-19 20:32:43 -0700141 free_backtrace_symbols(symbols, mCount);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800142}
143
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800144}; // namespace android