• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "CallStack"
18 
19 #include <string.h>
20 
21 #include <utils/Log.h>
22 #include <utils/Errors.h>
23 #include <utils/CallStack.h>
24 #include <corkscrew/backtrace.h>
25 
26 /*****************************************************************************/
27 namespace android {
28 
CallStack()29 CallStack::CallStack() :
30         mCount(0) {
31 }
32 
CallStack(const char * logtag,int32_t ignoreDepth,int32_t maxDepth)33 CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
34     this->update(ignoreDepth+1, maxDepth);
35     this->dump(logtag);
36 }
37 
CallStack(const CallStack & rhs)38 CallStack::CallStack(const CallStack& rhs) :
39         mCount(rhs.mCount) {
40     if (mCount) {
41         memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
42     }
43 }
44 
~CallStack()45 CallStack::~CallStack() {
46 }
47 
operator =(const CallStack & rhs)48 CallStack& CallStack::operator = (const CallStack& rhs) {
49     mCount = rhs.mCount;
50     if (mCount) {
51         memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
52     }
53     return *this;
54 }
55 
operator ==(const CallStack & rhs) const56 bool CallStack::operator == (const CallStack& rhs) const {
57     if (mCount != rhs.mCount)
58         return false;
59     return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
60 }
61 
operator !=(const CallStack & rhs) const62 bool CallStack::operator != (const CallStack& rhs) const {
63     return !operator == (rhs);
64 }
65 
operator <(const CallStack & rhs) const66 bool CallStack::operator < (const CallStack& rhs) const {
67     if (mCount != rhs.mCount)
68         return mCount < rhs.mCount;
69     return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
70 }
71 
operator >=(const CallStack & rhs) const72 bool CallStack::operator >= (const CallStack& rhs) const {
73     return !operator < (rhs);
74 }
75 
operator >(const CallStack & rhs) const76 bool CallStack::operator > (const CallStack& rhs) const {
77     if (mCount != rhs.mCount)
78         return mCount > rhs.mCount;
79     return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
80 }
81 
operator <=(const CallStack & rhs) const82 bool CallStack::operator <= (const CallStack& rhs) const {
83     return !operator > (rhs);
84 }
85 
operator [](int index) const86 const void* CallStack::operator [] (int index) const {
87     if (index >= int(mCount))
88         return 0;
89     return reinterpret_cast<const void*>(mStack[index].absolute_pc);
90 }
91 
clear()92 void CallStack::clear() {
93     mCount = 0;
94 }
95 
update(int32_t ignoreDepth,int32_t maxDepth)96 void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
97     if (maxDepth > MAX_DEPTH) {
98         maxDepth = MAX_DEPTH;
99     }
100     ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
101     mCount = count > 0 ? count : 0;
102 }
103 
dump(const char * logtag,const char * prefix) const104 void CallStack::dump(const char* logtag, const char* prefix) const {
105     backtrace_symbol_t symbols[mCount];
106 
107     get_backtrace_symbols(mStack, mCount, symbols);
108     for (size_t i = 0; i < mCount; i++) {
109         char line[MAX_BACKTRACE_LINE_LENGTH];
110         format_backtrace_line(i, &mStack[i], &symbols[i],
111                 line, MAX_BACKTRACE_LINE_LENGTH);
112         ALOG(LOG_DEBUG, logtag, "%s%s",
113                 prefix ? prefix : "",
114                 line);
115     }
116     free_backtrace_symbols(symbols, mCount);
117 }
118 
toString(const char * prefix) const119 String8 CallStack::toString(const char* prefix) const {
120     String8 str;
121     backtrace_symbol_t symbols[mCount];
122 
123     get_backtrace_symbols(mStack, mCount, symbols);
124     for (size_t i = 0; i < mCount; i++) {
125         char line[MAX_BACKTRACE_LINE_LENGTH];
126         format_backtrace_line(i, &mStack[i], &symbols[i],
127                 line, MAX_BACKTRACE_LINE_LENGTH);
128         if (prefix) {
129             str.append(prefix);
130         }
131         str.append(line);
132         str.append("\n");
133     }
134     free_backtrace_symbols(symbols, mCount);
135     return str;
136 }
137 
138 }; // namespace android
139