Android下打印调用栈

本文介绍如何在Java和C/C++层打印调用栈。在Java层,通过获取当前线程的StackTraceElement数组实现;在C/C++层,则利用CallStack类完成。这两种方法有助于调试和性能分析。

1. Java层如何打印调用栈?

在优化Android启动过程时,同事给出一种打印出调用栈的函数。分享一下

    java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();   
    StackTraceElement[] ste = ts.get(Thread.currentThread());   
    for (StackTraceElement s : ste) {   
        android.util.Slog.e("SS     ", s.toString()); //这个是android自带的,如果没有,用其他的打印函数一样   
    }  

为了打印出在android启动时,Zygote启动的所有java应用。在

    //frameworks/base/services/java/com/android/server/am/ActivityManagerService.java   
    private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {   
        //debug add   
        java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();   
        StackTraceElement[] ste = ts.get(Thread.currentThread());   
        for (StackTraceElement s : ste) {   
            android.util.Slog.e("SS     ", s.toString());   
        }        
    }

就可以在终端中使用命令logcat来查看打印出的调用栈了。

 

2. C/C++层如何打印调用栈?

Java可以方便的打印函数的调用栈。C/C++也可以。
为了显示在vm/Misc.cpp中谁调用了函数dvmAllocRegion,在这个函数中加入下面红色代码:
#include <utils/CallStack.h>
...

void *dvmAllocRegion(size_t byteCount, int prot, const char *name) 
{
    ...
#ifdef _ARM_
    LOGW("name=%s", name);
    android::CallStack stack;
    stack.update(1, 100);
    stack.dump("");
#endif
...
}

在vm/Dvm.mk中,加入:
  LOCAL_CFLAGS += -D_ARM_
  LOCAL_SHARED_LIBRARIES += libutils

"mmm dalvik" 得到libdvm.so。然后
adb root
adb remount
adb push libdvm.so /system/lib
adb reboot
系统重启后,新的libdvm.so就投入使用了。

Android应用开发中,打印异常调用栈信息是调试过程中非常重要的手段,可以帮助开发者快速定位问题所在。以下是几种常用的方法来实现这一功能。 ### 使用 `Exception` 对象打印堆栈 通过创建一个 `Exception` 对象并调用其 `printStackTrace()` 方法,可以将堆栈跟踪信息输出到控制台。这种方式适用于需要手动记录特定位置的堆栈信息的情况: ```java Exception e = new Exception("this is a log"); e.printStackTrace(); ``` 该方法会输出完整的堆栈信息,包括异常消息、抛出异常的位置以及调用链[^1]。 ### 利用 `Log` 类结合 `Throwable` 打印堆栈 如果希望将堆栈信息写入日志文件或查看更详细的运行时上下文,则可以通过 `Log.getStackTraceString()` 方法获取堆栈字符串,并使用 `Log.e()` 写入错误级别的日志: ```java Log.e("dump_test", Log.getStackTraceString(new Throwable())); ``` 此方法生成的日志条目会被记录在系统日志中,便于后续通过 `logcat` 工具检索和分析[^1]。 ### 在异常捕获时打印堆栈 当程序执行进入 `catch` 块时,为了了解具体的异常原因及其发生的上下文环境,通常也会在此处调用 `printStackTrace()` 方法: ```java try { // 可能引发异常的操作 } catch (Exception e) { e.printStackTrace(); } ``` 这样可以在发生异常时立即获得相关的调用栈信息,有助于快速识别和修复问题[^3]。 ### 查看 Logcat 中的堆栈信息 一旦上述代码被执行,相关信息就会出现在 Android Studio 的 **Logcat** 面板中。为了过滤出感兴趣的日志条目,可以在 Logcat 窗口中输入关键字(如标签名 `"dump_test"`),或者选择特定的日志级别(例如 Error)。此外,还可以利用命令行工具查看设备上的日志输出: ```bash adb logcat -s dump_test:E *:S ``` 这条命令只会显示标记为 `"dump_test"` 的错误级日志,从而简化了日志审查过程[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值