Android NDK开发

NDK开发(四)--NDK调试

2019-11-24  本文已影响0人  骑着蜗牛闯世界666

崩溃日志分析

在ndk崩溃的时候,如果是习惯JAVA 开发的同学,可能会毫无头绪,因为其崩溃信息并不像JAVA那样清晰,如果不知道各个部分的错误信息是代表啥意思,可能在出现问题的时候,不知道从何入手解决。


-w1355

上面是一个比较全的NDK崩溃堆栈。基本上一个崩溃日志可以分为三部分:错误信号寄存器信息方法调用栈

从错误信号里面,一般会告知,是哪种类型的异常,譬如上面的错误,提示了,导致的原因是空指针。
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 Cause: null pointer dereference

暂时不依赖这部分分析。

是调用了哪个方法导致的异常。有一系列的调用堆栈信息。

常见的NDK崩溃

指向了一个无效的地址

void errorAddressCrash() {
    //没有分配地址
    int *p;
    //进行赋值
    *p = 1;
}

解决方式是在定义的时候,需要进行初始化;在释放了指针指向的内存后,要把该指针置为NULL

//空指针异常 void nullPointCrash() { int *p = NULL; *p = 1; printf("%d\n", *p); }
解决方式一般是在使用的时候,增加空判断,如上面的栗子,增加if (p != NULL){}

这种比较容易理解,譬如定义了int data[10];但我们访问了data[11];
解决方式就是在使用之前,对其长度进行判断。

C语言不像JAVA 一样,需要自己进行内存管理,所以在使用的时候,需要注意内存释放。内存泄露一般都是在使用之后没有进行释放.

当使用了大量的局部引用而没有及时释放的话,就可能出现局部引用表溢出,所以变量用完以后需要回收一下

local reference table overflow (max=512)

如上面的解决方式可以是(*env)->DeleteLocalRef(env, jobject);

符号表

符号表就是内存地址与函数名、文件名、行号的映射表。如下,在AS打包的时候,一般都会生成两个以上的so,其中obj 目录下的so 是带符号表的,另外两个目录下的so 是不带符号表的。


-w1349

另外,带符号表的和不带符号表的so的体积,会有较大的差别。
app/build/intermediates/cmake/debug/obj/x86/目录下的

→ ls|xargs du -sh                                                                                                                                                                     [07cec0a]
  0B    arm64-v8a
  0B    armeabi-v7a
1.1M    x86
  0B    x86_64

app/build/intermediates/transforms/stripDebugSymbol/debug/0/lib/x86/目录下的

ls|xargs du -sh                                                                                                                                                                     [07cec0a]
200K    x86

可以看到,两个体积相差将近5倍左右。

上一篇下一篇

猜你喜欢

热点阅读