哈喽,大家好,我是LittleG。
编程语言是工具,在实际工作中我们可能往往会用到一种编程语言工具或者多种编程语言工具才能实现一个完整功能的需求;尤其是在 Android 的开发过程中,从上层到底层,涉及 java、C++、C,而且目前看谷歌正在部署引入新的开发语言 Rust ,大有替代 C++ 和 C 部分功能实现的趋势;下一步,我们很有可能又得再多学习一门编程语言了。
在实际开发中,因为经常分析问题,需要从上到下跟踪一些代码调用流程,所以就会有分别在 java、native、kernel 打印调用堆栈的需求;之前也都是零散的在用,今天花了一些时间,梳理了一下,记录分享之。
正文
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> //在想调用Callstack的函数中加入如下代码: 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,其原型可以看到也是调了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 信号,系统默认会忽略此信号;但是如果目标进程捕获了该信号,因为信号会导致 kernel 可中断任务(TASK_INTERRUPTIBLE)被唤醒,进而可能导致用户进程一些系统调用(select、read、sleep 等)返回异常,此时如果不配合做一些处理,就可能导致进程异常退出。
2、利用 tombstone
机制:
进程 crash,即可触发生成/data/tombstone 目录文件,手动导出即可。可以使用类似“ kill -11 ”的命令,注意确认进程本身没有捕获 SIGSEGV,不然就不会发生 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 ......
如果你有更好的方法和经验,欢迎交流,谢谢~