Dalvik虚拟机异常处理

2019-04-15  本文已影响0人  程序设计法师
方法调用栈

java虚拟机用方法调用栈来跟踪一系列的方法调用过程,该堆栈保存了每个调用方法的本地信息,比如方法的局部变量,当一个新方法被调用时,java虚拟机会把描述该方法的栈结构置入栈顶,位于栈顶的方法为正在执行的方法

Main()的栈结构->MethodB()的栈结构->methodA()的栈结构->栈顶部的方法是正在执行的方法

当MethodB()调用MethodA()时,如果方法中的代码块可能抛出异常,有两种处理办法:
1 如果当前方法有能力自己解决异常,就在当前方法中通过try catch语句捕获并处理
2 如果当前方法没有能力自己处理异常,就在方法的声明处通过throws声明抛出异常如下:

public void methodA()throws SpecialException{
    //以下代码可能会抛出SpecialException
    if(status==-1){
      throw new SpecialException("Monster");    
}
}

此时Java虚拟机的处理流程将退回到上层调用方法MethodB(),再查看MethodB()中有没有捕获SpecialException,如果在其中存在捕获该异常的catch代码块,就执行这个catch代码块,否则将继续往上查找catch代码块,如果main()中仍然没有找到处理该异常的代码块,将调用异常对象的printStackTrace()方法,打印来自方法调用栈的异常信息,随后整个应用程序被终止。

java中有个lang包,此包里有个专门处理异常的类Throwable,此类是所有异常的父类,每一个异常的类都是他的子类,其中Error和Exception这两个类非常重要,前者用来定义那些通常情况下不希望被捕获的异常,而后者是程序能够捕获的异常情况

及时编译执行时,异常的传播处理较为复杂,这需要对本地方法栈的结构有一个清楚的认识,线程在创建时JVM为其分配一个固定的运行空间(可由用户指定),线程的一切活动所需的空间都被分配在该空间中,对于及时编译,该空间存放本地方法栈,本地方法栈实际上就是传统的C栈,要实现异常在方法调用栈中的传播,我们就得解决如何确定产生异常方法栈的位置,及调用该方法的上层方法的栈的位置


线程.png

上图方法的调用过程为方法1调用方法2,方法2调用方法3

Java应用输出堆栈信息

要想在Java应用中输出Callback Stack信息,可以借助catch exception语句,并使用Log.w(LOGTAG,Log.getStackTraceString(throwable))来输出调用堆栈信息,例如下面代码

Throwable throw=new Throwable();
Log.w(LOGTAG,Log.getStackTraceString(throw))

或者使用如下方法

try{
  wait();    
}catch(InterruptedException e){
  Log.e(LOGTAG,Log.getStackTraceString(e));
}
安卓底层开发获取堆栈信息

使用ndk-stack工具保存出错log为logcat.log的方式

cat logcat..log|ndk-stack-sym ~/[SOURCE-DIR]/out/target/product/[PROJECT]/symbols/system/lib/

也可以使用arm-linux-addr2line命令获取调用堆栈信息的输出

arm-eabi-addr2line-C -f -e symbols/system/lib/*.so addr
上一篇下一篇

猜你喜欢

热点阅读