NDK开发(四)--NDK调试

崩溃日志分析

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


-w1355

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

  • 1、错误信号

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

  • 2、寄存器信息

暂时不依赖这部分分析。

  • 3、方法调用栈

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

常见的NDK崩溃

  • 1、野指针

指向了一个无效的地址

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

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

  • 2、空指针

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

  • 3、数组越界

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

  • 4、内存泄露

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

  • 5、堆栈溢出

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

local reference table overflow (max=512)

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

符号表

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


NDK开发(四)--NDK调试_第1张图片
-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倍左右。

你可能感兴趣的:(NDK开发(四)--NDK调试)