Android代碼流程比較複雜,單純看代碼很容易跟丟,如果能在對應位置增加調用棧函數,運行時,我們可以根據調用棧來退出安卓代碼的調用流程,可以事半功倍。
1、java代碼
java代碼中加調用棧方法很簡單,拋一個異常即可。
import android.util.Log;
Log.i(TAG, Log.getStackTraceString(new Throwable()));
注意,有的java文件中使用了Slog.i 來打印信息, Slog實際封裝了Log的部分方法,但是沒有封裝getStackTraceString此方法,
故打印調用棧時,只能使用Log,而不能使用Slog.
2. C++代碼
C++中也較簡單
#include <utils/CallStack.h>
void print_stack(void) {
android::CallStack stack;
stack.update();
stack.log(LOG_TAG);
}
增加如上代碼,再直接調用print_stack() 函數即可。
3. C代碼
C代碼中沒有調用棧相關的函數,需要我們使用C++的方法。
簡單來說
1、 在相應模塊新建一cpp文件, test.cpp, 拷貝如下代碼:
#include <utils/CallStack.h>
extern "C" void printCallStack();
void printCallStack() {
android::CallStack stk("Test");
}
2、mk中增加相關代碼,保證可以編譯到此文件
LOCAL_SHARED_LIBRARIES += libutils
LOCAL_SRC_FILES += test.cpp
3、使用的文件中增加聲明
extern void printCallStack();
4、 直接使用
在需要使用的地方寫 printCallStack(); 即可。
4. 內核代碼
直接使用
dump_stack();
即可
其他
針對C/C++打印出的調用棧,我們將調用棧信息拷貝到一文件中,如 1.txt
並放到配置環境的代碼中,使用stack 1.txt 可以將調用棧信息轉換爲具體的行號
stack腳本會根據android代碼配置的環境變量,自動查找symbols目錄下的符號信息,
自動調用arm-linux-androideabi-addr2line/aarch64-linux-android-addr2line 根據符號表將調用棧信息轉換具體的行號,可以大大提高我們的調試效率。