Java
非常简单,创建一个 Throwable 对象,就可以得到当前的 stack trace。下面例子是打出调用 foobar() 函数的 trace:
1 2 3 4
| private void foobar() { Throwable t = new Throwable(); Log.d(TAG, "stack trace is ", t); }
|
C++
Android 4.4 及之前版本
也比较简单,使用 utils/Callstack 类即可。头文件位于 frameworks/native/include/utils/CallStack.h,一般无需修改 Android.mk 可直接使用。
1 2 3 4 5 6 7
| #include <utils/CallStack.h>
void Foo::bar() { CallStack *t = new CallStack("Trace", 2); delete t; }
|
Android 5.0
Android 5.0 以后需要头文件位置改变,需在 Android.mk 加入 system/core/include,调用方法同上
C
Android 4.4 及之前版本
稍微麻烦一点,需要直接调用 corkscrew/backtrace。其实 C++ 里的 utils/Callstack 也是使用 corkscrew/backtrace,只是进行了封装更易于使用。我们参照 CallStack.cpp 里面代码即可。下面例子是打出调用 foobar() 函数的 trace:
NOTE: C 不能直接调用 C++ 代码,除非在 C++ 类中添加相应的 C wrapper,或者通过 dlsym 动态载入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <corkscrew/backtrace.h>
void dumpStackTrace(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) const { static const int MAX_DEPTH = 31; static const int MAX_BACKTRACE_LINE_LENGTH = 800;
if (maxDepth > MAX_DEPTH) { maxDepth = MAX_DEPTH; } backtrace_frame_t mStack[MAX_DEPTH]; ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth); if (count <= 0) { LOGE("Can not get stack trace"); return; } backtrace_symbol_t symbols[count];
get_backtrace_symbols(mStack, count, symbols); for (size_t i = 0; i < count; 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", "", line); } free_backtrace_symbols(symbols, count); }
void foobar() { dumpStackTrace("Trace", 1, 30); }
|
头文件位于 system/core/include/corkscrew/backtrace.h,在 Android.mk 中还需要加入:
1
| LOCAL_SHARED_LIBRARIES += libcorkscrew
|
本博客微信公众号