為什么要打印函數調用堆棧?
打印調用堆棧可以直接把問題發生時的函數調用關系打出來,非常有利於理解函數調用關系。比如函數A都有可能,如果打印出調用堆棧,直接就把誰調的打出來了。
不僅如此,打印函數調用堆棧還有另一個好處。在Android工具看也未必容易看清函數調用關系。如果用了堆棧打印,很容易看到函數調用邏輯。
那么一個問題來了,Android/kernel系統運行的境況下,打印出某個情形下的堆棧信息,這個對源代碼邏輯研究很有幫助。
Linux Kernel
Kernel里最簡單,直接有幾現成的函數可以使用:
dump_stack() 這個函數打出當前堆棧和函數調用backtrace后接着運行
WARN_ON(x) 這個函數跟dump_stack打出來。
打印出來的結果都在kernel log命令就可以看到了
Native C++
Android。用法很簡單:
前面確保包含頭文件#include
Android.mk,一般都已經包含了。
然后在要打印堆棧處加入android::CallStack cs(“haha”);
“haha”前綴就不必加了。
Native C++里看到。
注意,在網上的一些文檔里說要這么用:
CallStack stack;
stack.update();
stack.dump();
這樣做已經不行了,在新版Android里編譯不過。
Native C
Android庫的方法自然就不能用了。
一個簡單方法是用C。
先在項目里加入一個c++,里面是:
#include
extern "C" void dumping_callstack(void);
void dumping_callstack(void)
{
android::CallStack cs("Jamie");
}
在項目里再加入一個c++,里面是:
void dumping_callstack(void);
在Android.mk在依賴列表里。
在native C就可以了。
這個log里看到。
Java最詳細,連文件名和行號都打出來了:
Exception e = new Exception("haha");
e.printStackTrace();
log里看以看到。