哈嘍,大家好,我是LittleG。
編程語言是工具,在實際工作中我們可能往往會用到一種編程語言工具或者多種編程語言工具才能實現(xiàn)一個完整功能的需求;尤其是在 Android 的開發(fā)過程中,從上層到底層,涉及 java、C++、C,而且目前看谷歌正在部署引入新的開發(fā)語言 Rust ,大有替代 C++ 和 C 部分功能實現(xiàn)的趨勢;下一步,我們很有可能又得再多學習一門編程語言了。
在實際開發(fā)中,因為經(jīng)常分析問題,需要從上到下跟蹤一些代碼調(diào)用流程,所以就會有分別在?java、native、kernel 打印調(diào)用堆棧的需求;之前也都是零散的在用,今天花了一些時間,梳理了一下,記錄分享之。
正文
Android java、native、kernel打印堆棧常用方法總結:
一、java
import android.util.Log; Log.e("LOG_TAG", "log info", Log.getStackTraceString(new Throwable())); //或者 android.util.Log.e("LOG_TAG", "log info", android.util.Log.getStackTraceString(new Throwable()));
二、native
//mk添加: LOCAL_SHARED_LIBRARIES += libutils libutilscallstack //頭文件添加: #include <log/log.h> #include <utils/CallStack.h> //在想調(diào)用Callstack的函數(shù)中加入如下代碼: android::CallStack callstack; callstack.update(); callstack.log("LOG_TAG", ANDROID_LOG_INFO, "xxxx");//LOG_TAG是TAG;xxxx是backtrace的前綴; //或者 android::CallStack stack("my_test");
三、kernel
#include "linux/printk.h" //常用dump_stack,打印堆棧信息 dump_stack(); //或者可用WARN_ON,其原型可以看到也是調(diào)了dump_stack,打印堆棧信息,不會OOPS; WARN_ON(xxxx == yyyy); #define WARN_ON(condition) do { / ? ? ?if (unlikely((condition)!=0)) { / ? ? ? ? ?printk("Badness in %s at %s:%d/n", __FUNCTION__, __FILE__,__LINE__); / ? ? ? ? ?dump_stack(); / ? ? } / } while (0) //如果想OOPS,可以使用 BUG_ON BUG_ON(bad_thing);
四、通過 debuggerd命令 或者 tombstone機制獲取堆棧信息
1、使用debuggerd
命令:
root:/ # debuggerd -h usage: debuggerd [-bj] PID -b, --backtrace ? just a backtrace rather than a full tombstone -j ? ? ? ? ? ? ? ? collect java traces root:/ # debuggerd -b 1884
說明:以上 1884 是 pid。正常情況,使用 debuggerd 并不會導致進程異常退出。使用該命令時,目標進程會收到一個 SIGCHLD 信號,系統(tǒng)默認會忽略此信號;但是如果目標進程捕獲了該信號,因為信號會導致 kernel 可中斷任務(TASK_INTERRUPTIBLE)被喚醒,進而可能導致用戶進程一些系統(tǒng)調(diào)用(select、read、sleep 等)返回異常,此時如果不配合做一些處理,就可能導致進程異常退出。
2、利用 tombstone
機制:
進程?crash,即可觸發(fā)生成/data/tombstone?目錄文件,手動導出即可??梢允褂妙愃啤?kill -11 ”的命令,注意確認進程本身沒有捕獲 SIGSEGV,不然就不會發(fā)生 crash 了 。
root:/ # kill -11 1884
說明:以上 1884 是 pid。
附:kill 命令 signals
:
root:/ # kill -l 1 ?? HUP Hangup ? ? ? ? ? ? ? ? ? ? ? 2? ? INT Interrupt ? ? ? ? ? ? ? ? ? ? 3? ? QUIT Quit ? ? ? ? ? ? ? ? ? ? ? ? 4? ? ILL Illegal instruction ? ? ? ? ? 5? ? TRAP Trap ? ? ? ? ? ? ? ? ? ? ? ? 6? ? ABRT Aborted ? ? ? ? ? ? ? ? ? ? ? 7? ? BUS Bus error ? ? ? ? ? ? ? ? ? ? 8? ? FPE Floating point exception ? ? 9? ? KILL Killed ? ? ? ? ? ? ? ? ? ? ? 10 ? USR1 User signal 1 ? ? ? ? ? ? ? ? 11 ? SEGV Segmentation fault ? ? ? ? ? 12 ? USR2 User signal 2 ? ? ? 13 ? PIPE Broken pipe ? ? ? ? 14 ? ALRM Alarm clock ? ? ? ? 15 ? TERM Terminated ? ? ? ? ? 16? ?STKFLT Stack fault ? ? ? ? 17 ? CHLD Child exited ? ? ? ? 18 ? CONT Continue ? ? ? ? ? ? 19 ? STOP Stopped (signal) ? ? 20 ? TSTP Stopped ? ? ? ? ? ? 21 ? TTIN Stopped (tty input) 22 ? TTOU Stopped (tty output) 23 ? URG Urgent I/O condition ? ? 24 ? XCPU CPU time limit exceeded 25 ? XFSZ File size limit exceeded 26? ?VTALRM Virtual timer expired ? 27 ? PROF Profiling timer expired 28? ?WINCH Window size changed ? ? 29 ? IO I/O possible ? ? ? ? ? ? 30 ? PWR Power failure ? ? ? ? ? 31 ? SYS Bad system call ? ? ? ? 32 ? Signal 32 ? ? ? ? ? ? ? 33 ? Signal 33 ......
如果你有更好的方法和經(jīng)驗,歡迎交流,謝謝~