diff options
author | Alex Ray <aray@google.com> | 2013-08-02 14:40:08 -0700 |
---|---|---|
committer | Alex Ray <aray@google.com> | 2013-08-02 14:40:08 -0700 |
commit | d98e07fdf9c338589f263c47ce5c844ed43efad5 (patch) | |
tree | d4ff9849df225df1e4c46386fdabe30407ba5513 /libutils/CallStack.cpp | |
parent | be06210c508d5878dcc7d185e5613f4c7e38dfe8 (diff) | |
download | system_core-d98e07fdf9c338589f263c47ce5c844ed43efad5.zip system_core-d98e07fdf9c338589f263c47ce5c844ed43efad5.tar.gz system_core-d98e07fdf9c338589f263c47ce5c844ed43efad5.tar.bz2 |
move libs/utils to libutils
Change-Id: I6cf4268599460791414882f91eeb88a992fbd29d
Diffstat (limited to 'libutils/CallStack.cpp')
-rw-r--r-- | libutils/CallStack.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp new file mode 100644 index 0000000..e60f5d8 --- /dev/null +++ b/libutils/CallStack.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CallStack" + +#include <string.h> + +#include <utils/Log.h> +#include <utils/Errors.h> +#include <utils/CallStack.h> +#include <corkscrew/backtrace.h> + +/*****************************************************************************/ +namespace android { + +CallStack::CallStack() : + mCount(0) { +} + +CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) { + this->update(ignoreDepth+1, maxDepth); + this->dump(logtag); +} + +CallStack::CallStack(const CallStack& rhs) : + mCount(rhs.mCount) { + if (mCount) { + memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); + } +} + +CallStack::~CallStack() { +} + +CallStack& CallStack::operator = (const CallStack& rhs) { + mCount = rhs.mCount; + if (mCount) { + memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); + } + return *this; +} + +bool CallStack::operator == (const CallStack& rhs) const { + if (mCount != rhs.mCount) + return false; + return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0; +} + +bool CallStack::operator != (const CallStack& rhs) const { + return !operator == (rhs); +} + +bool CallStack::operator < (const CallStack& rhs) const { + if (mCount != rhs.mCount) + return mCount < rhs.mCount; + return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0; +} + +bool CallStack::operator >= (const CallStack& rhs) const { + return !operator < (rhs); +} + +bool CallStack::operator > (const CallStack& rhs) const { + if (mCount != rhs.mCount) + return mCount > rhs.mCount; + return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0; +} + +bool CallStack::operator <= (const CallStack& rhs) const { + return !operator > (rhs); +} + +const void* CallStack::operator [] (int index) const { + if (index >= int(mCount)) + return 0; + return reinterpret_cast<const void*>(mStack[index].absolute_pc); +} + +void CallStack::clear() { + mCount = 0; +} + +void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) { + if (maxDepth > MAX_DEPTH) { + maxDepth = MAX_DEPTH; + } + ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth); + mCount = count > 0 ? count : 0; +} + +void CallStack::dump(const char* logtag, const char* prefix) const { + backtrace_symbol_t symbols[mCount]; + + get_backtrace_symbols(mStack, mCount, symbols); + for (size_t i = 0; i < mCount; i++) { + char line[MAX_BACKTRACE_LINE_LENGTH]; + format_backtrace_line(i, &mStack[i], &symbols[i], + line, MAX_BACKTRACE_LINE_LENGTH); + ALOG(LOG_DEBUG, logtag, "%s%s", + prefix ? prefix : "", + line); + } + free_backtrace_symbols(symbols, mCount); +} + +String8 CallStack::toString(const char* prefix) const { + String8 str; + backtrace_symbol_t symbols[mCount]; + + get_backtrace_symbols(mStack, mCount, symbols); + for (size_t i = 0; i < mCount; i++) { + char line[MAX_BACKTRACE_LINE_LENGTH]; + format_backtrace_line(i, &mStack[i], &symbols[i], + line, MAX_BACKTRACE_LINE_LENGTH); + if (prefix) { + str.append(prefix); + } + str.append(line); + str.append("\n"); + } + free_backtrace_symbols(symbols, mCount); + return str; +} + +}; // namespace android |