1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/* 2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License. 6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at 7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and 14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License. 15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */ 16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define LOG_TAG "CallStack" 18cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <string.h> 20cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 21cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Log.h> 22cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Errors.h> 23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/CallStack.h> 24ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown#include <corkscrew/backtrace.h> 25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*****************************************************************************/ 27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android { 28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 29ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff BrownCallStack::CallStack() : 30ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown mCount(0) { 31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 33d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias AgopianCallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) { 34d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian this->update(ignoreDepth+1, maxDepth); 35d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian this->dump(logtag); 36d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian} 37d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian 38ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff BrownCallStack::CallStack(const CallStack& rhs) : 39ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown mCount(rhs.mCount) { 40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mCount) { 41ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); 42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 45ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff BrownCallStack::~CallStack() { 46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 47cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 48ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff BrownCallStack& CallStack::operator = (const CallStack& rhs) { 49cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mCount = rhs.mCount; 50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mCount) { 51ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); 52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator == (const CallStack& rhs) const { 57cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mCount != rhs.mCount) 58cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return false; 59ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0; 60cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 61cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 62cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator != (const CallStack& rhs) const { 63cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return !operator == (rhs); 64cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 65cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 66cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator < (const CallStack& rhs) const { 67cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mCount != rhs.mCount) 68cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return mCount < rhs.mCount; 69ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0; 70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 71cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator >= (const CallStack& rhs) const { 73cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return !operator < (rhs); 74cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 75cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 76cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator > (const CallStack& rhs) const { 77cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mCount != rhs.mCount) 78cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return mCount > rhs.mCount; 79ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0; 80cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 81cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 82cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool CallStack::operator <= (const CallStack& rhs) const { 83cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return !operator > (rhs); 84cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 85cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 86cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectconst void* CallStack::operator [] (int index) const { 87cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (index >= int(mCount)) 88cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return 0; 89ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown return reinterpret_cast<const void*>(mStack[index].absolute_pc); 90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 92ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brownvoid CallStack::clear() { 93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mCount = 0; 94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 95cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 96ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brownvoid CallStack::update(int32_t ignoreDepth, int32_t maxDepth) { 97ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown if (maxDepth > MAX_DEPTH) { 98cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project maxDepth = MAX_DEPTH; 99cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 100ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth); 101ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown mCount = count > 0 ? count : 0; 102ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown} 103ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown 104d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopianvoid CallStack::dump(const char* logtag, const char* prefix) const { 105ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown backtrace_symbol_t symbols[mCount]; 106ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown 107ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown get_backtrace_symbols(mStack, mCount, symbols); 108ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown for (size_t i = 0; i < mCount; i++) { 10911189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown char line[MAX_BACKTRACE_LINE_LENGTH]; 11011189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown format_backtrace_line(i, &mStack[i], &symbols[i], 11111189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown line, MAX_BACKTRACE_LINE_LENGTH); 112d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian ALOG(LOG_DEBUG, logtag, "%s%s", 113d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian prefix ? prefix : "", 114d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian line); 115cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 116ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown free_backtrace_symbols(symbols, mCount); 117ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown} 118ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown 119ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff BrownString8 CallStack::toString(const char* prefix) const { 120ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown String8 str; 121ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown backtrace_symbol_t symbols[mCount]; 122ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown 123ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown get_backtrace_symbols(mStack, mCount, symbols); 124ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown for (size_t i = 0; i < mCount; i++) { 12511189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown char line[MAX_BACKTRACE_LINE_LENGTH]; 12611189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown format_backtrace_line(i, &mStack[i], &symbols[i], 12711189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown line, MAX_BACKTRACE_LINE_LENGTH); 12899ec303e459ea4ded9981337e10651aee08016b0Marco Nelissen if (prefix) { 12999ec303e459ea4ded9981337e10651aee08016b0Marco Nelissen str.append(prefix); 13099ec303e459ea4ded9981337e10651aee08016b0Marco Nelissen } 13111189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown str.append(line); 13211189f5f797ef29ee670ab4683f97c2cfc109899Jeff Brown str.append("\n"); 133cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 134ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown free_backtrace_symbols(symbols, mCount); 135ea45b01f9bc2d1ef1f8d97ca0480336d23e0aa97Jeff Brown return str; 136cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 137cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android 139