加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

Android java、native、kernel获取堆栈信息常用方法总结

2023/08/25
6774
阅读需 9 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

哈喽,大家好,我是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
......

如果你有更好的方法和经验,欢迎交流,谢谢~

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
BCM5241A1IMLG 1 Broadcom Limited Ethernet Transceiver, PACKAGE
$3.42 查看
ASDMB-20.000MHZ-LC-T 1 Abracon Corporation MEMS OSC XO 20.0000MHZ LVCMOS

ECAD模型

下载ECAD模型
$1.94 查看
TF202P32K7680R 1 CTS Corporation Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom,
$3.82 查看

相关推荐

电子产业图谱

记录和分享C/C++、Linux、ARM、Android、IoT相关知识。技术相伴于生活和成长,愿你我永为少年,心中有火,眼中有光,始保热情。