使用調用棧來調試Android代碼

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 根據符號表將調用棧信息轉換具體的行號,可以大大提高我們的調試效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章