blob: c2a5e5534f3ae275de4b36de4485d3e738ee2cf1 [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
Jeff Brownea45b012011-10-19 20:32:43 -070033CallStack::CallStack(const CallStack& rhs) :
34 mCount(rhs.mCount) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080035 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070036 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080037 }
38}
39
Jeff Brownea45b012011-10-19 20:32:43 -070040CallStack::~CallStack() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080041}
42
Jeff Brownea45b012011-10-19 20:32:43 -070043CallStack& CallStack::operator = (const CallStack& rhs) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080044 mCount = rhs.mCount;
45 if (mCount) {
Jeff Brownea45b012011-10-19 20:32:43 -070046 memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080047 }
48 return *this;
49}
50
51bool CallStack::operator == (const CallStack& rhs) const {
52 if (mCount != rhs.mCount)
53 return false;
Jeff Brownea45b012011-10-19 20:32:43 -070054 return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080055}
56
57bool CallStack::operator != (const CallStack& rhs) const {
58 return !operator == (rhs);
59}
60
61bool CallStack::operator < (const CallStack& rhs) const {
62 if (mCount != rhs.mCount)
63 return mCount < rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070064 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080065}
66
67bool CallStack::operator >= (const CallStack& rhs) const {
68 return !operator < (rhs);
69}
70
71bool CallStack::operator > (const CallStack& rhs) const {
72 if (mCount != rhs.mCount)
73 return mCount > rhs.mCount;
Jeff Brownea45b012011-10-19 20:32:43 -070074 return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080075}
76
77bool CallStack::operator <= (const CallStack& rhs) const {
78 return !operator > (rhs);
79}
80
81const void* CallStack::operator [] (int index) const {
82 if (index >= int(mCount))
83 return 0;
Jeff Brownea45b012011-10-19 20:32:43 -070084 return reinterpret_cast<const void*>(mStack[index].absolute_pc);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080085}
86
Jeff Brownea45b012011-10-19 20:32:43 -070087void CallStack::clear() {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080088 mCount = 0;
89}
90
Jeff Brownea45b012011-10-19 20:32:43 -070091void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
92 if (maxDepth > MAX_DEPTH) {
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080093 maxDepth = MAX_DEPTH;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080094 }
Jeff Brownea45b012011-10-19 20:32:43 -070095 ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
96 mCount = count > 0 ? count : 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080097}
98
Jeff Brownea45b012011-10-19 20:32:43 -070099void CallStack::dump(const char* prefix) const {
100 backtrace_symbol_t symbols[mCount];
101
102 get_backtrace_symbols(mStack, mCount, symbols);
103 for (size_t i = 0; i < mCount; i++) {
Jeff Brown11189f52011-11-21 21:04:55 -0800104 char line[MAX_BACKTRACE_LINE_LENGTH];
105 format_backtrace_line(i, &mStack[i], &symbols[i],
106 line, MAX_BACKTRACE_LINE_LENGTH);
107 LOGD("%s%s", prefix, line);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800108 }
Jeff Brownea45b012011-10-19 20:32:43 -0700109 free_backtrace_symbols(symbols, mCount);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800110}
111
Jeff Brownea45b012011-10-19 20:32:43 -0700112String8 CallStack::toString(const char* prefix) const {
113 String8 str;
114 backtrace_symbol_t symbols[mCount];
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800115
Jeff Brownea45b012011-10-19 20:32:43 -0700116 get_backtrace_symbols(mStack, mCount, symbols);
117 for (size_t i = 0; i < mCount; i++) {
Jeff Brown11189f52011-11-21 21:04:55 -0800118 char line[MAX_BACKTRACE_LINE_LENGTH];
119 format_backtrace_line(i, &mStack[i], &symbols[i],
120 line, MAX_BACKTRACE_LINE_LENGTH);
121 str.append(prefix);
122 str.append(line);
123 str.append("\n");
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800124 }
Jeff Brownea45b012011-10-19 20:32:43 -0700125 free_backtrace_symbols(symbols, mCount);
126 return str;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800127}
128
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800129}; // namespace android