blob: e60f5d8e757e9e1482aebc9ca9361f49e962072f [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
19#include <string.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080020
21#include <utils/Log.h>
22#include <utils/Errors.h>
23#include <utils/CallStack.h>
Jeff Brownea45b012011-10-19 20:32:43 -070024#include <corkscrew/backtrace.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080025
26/*****************************************************************************/
27namespace android {
28
Jeff Brownea45b012011-10-19 20:32:43 -070029CallStack::CallStack() :
30 mCount(0) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080031}
32
Mathias Agopiand34a8ca2013-03-21 17:12:40 -070033CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
34 this->update(ignoreDepth+1, maxDepth);
35 this->dump(logtag);
36}
37
Jeff Brownea45b012011-10-19 20:32:43 -070038CallStack::CallStack(const CallStack& rhs) :
39 mCount(rhs.mCount) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080040 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070041 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080042 }
43}
44
Jeff Brownea45b012011-10-19 20:32:43 -070045CallStack::~CallStack() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080046}
47
Jeff Brownea45b012011-10-19 20:32:43 -070048CallStack& CallStack::operator = (const CallStack& rhs) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080049 mCount = rhs.mCount;
50 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070051 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080052 }
53 return *this;
54}
55
56bool CallStack::operator == (const CallStack& rhs) const {
57 if (mCount != rhs.mCount)
58 return false;
Jeff Brownea45b012011-10-19 20:32:43 -070059 return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080060}
61
62bool CallStack::operator != (const CallStack& rhs) const {
63 return !operator == (rhs);
64}
65
66bool CallStack::operator < (const CallStack& rhs) const {
67 if (mCount != rhs.mCount)
68 return mCount < rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070069 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080070}
71
72bool CallStack::operator >= (const CallStack& rhs) const {
73 return !operator < (rhs);
74}
75
76bool CallStack::operator > (const CallStack& rhs) const {
77 if (mCount != rhs.mCount)
78 return mCount > rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070079 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080080}
81
82bool CallStack::operator <= (const CallStack& rhs) const {
83 return !operator > (rhs);
84}
85
86const void* CallStack::operator [] (int index) const {
87 if (index >= int(mCount))
88 return 0;
Jeff Brownea45b012011-10-19 20:32:43 -070089 return reinterpret_cast<const void*>(mStack[index].absolute_pc);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080090}
91
Jeff Brownea45b012011-10-19 20:32:43 -070092void CallStack::clear() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080093 mCount = 0;
94}
95
Jeff Brownea45b012011-10-19 20:32:43 -070096void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
97 if (maxDepth > MAX_DEPTH) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080098 maxDepth = MAX_DEPTH;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080099 }
Jeff Brownea45b012011-10-19 20:32:43 -0700100 ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
101 mCount = count > 0 ? count : 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800102}
103
Mathias Agopiand34a8ca2013-03-21 17:12:40 -0700104void CallStack::dump(const char* logtag, const char* prefix) const {
Jeff Brownea45b012011-10-19 20:32:43 -0700105 backtrace_symbol_t symbols[mCount];
106
107 get_backtrace_symbols(mStack, mCount, symbols);
108 for (size_t i = 0; i < mCount; i++) {
Jeff Brown11189f52011-11-21 21:04:55 -0800109 char line[MAX_BACKTRACE_LINE_LENGTH];
110 format_backtrace_line(i, &mStack[i], &symbols[i],
111 line, MAX_BACKTRACE_LINE_LENGTH);
Mathias Agopiand34a8ca2013-03-21 17:12:40 -0700112 ALOG(LOG_DEBUG, logtag, "%s%s",
113 prefix ? prefix : "",
114 line);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800115 }
Jeff Brownea45b012011-10-19 20:32:43 -0700116 free_backtrace_symbols(symbols, mCount);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800117}
118
Jeff Brownea45b012011-10-19 20:32:43 -0700119String8 CallStack::toString(const char* prefix) const {
120 String8 str;
121 backtrace_symbol_t symbols[mCount];
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800122
Jeff Brownea45b012011-10-19 20:32:43 -0700123 get_backtrace_symbols(mStack, mCount, symbols);
124 for (size_t i = 0; i < mCount; i++) {
Jeff Brown11189f52011-11-21 21:04:55 -0800125 char line[MAX_BACKTRACE_LINE_LENGTH];
126 format_backtrace_line(i, &mStack[i], &symbols[i],
127 line, MAX_BACKTRACE_LINE_LENGTH);
Marco Nelissen99ec3032012-12-17 10:28:20 -0800128 if (prefix) {
129 str.append(prefix);
130 }
Jeff Brown11189f52011-11-21 21:04:55 -0800131 str.append(line);
132 str.append("\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800133 }
Jeff Brownea45b012011-10-19 20:32:43 -0700134 free_backtrace_symbols(symbols, mCount);
135 return str;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800136}
137
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800138}; // namespace android