类Unix平台程序调试

GNU Binutils

创建main.c文件,内容以下:html

#include <stdio.h>

void main()
{
    int a = 5/0;
}

编译main.c:linux

gcc -g main.c

生成a.out文件
执行a.out, ./a.out, 出现以下错误信息:android

Floating point exception (core dumped)ios

使用dmesg | tail命令查看:app

[   26.511616] VBoxPciLinuxInit
[   26.701426] vboxpci: IOMMU not found (not registered)
[ 4526.498595] usb 1-5: USB disconnect, device number 2
[ 4526.895918] usb 1-5: new high-speed USB device number 3 using ehci-pci
[ 4527.045378] usb 1-5: New USB device found, idVendor=2717, idProduct=ff48
[ 4527.045381] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4527.045383] usb 1-5: Product: MI MAX 2
[ 4527.045385] usb 1-5: Manufacturer: Xiaomi
[ 4527.045387] usb 1-5: SerialNumber: 8fc7deed
[31563.822978] traps: a.out[19804] trap divide error ip:4004e5 sp:7ffdd3cf89c0 error:0 in a.out[400000+1000]

根据错误地址(ip后面的地址),使用以下命令,能够定位(输出)函数名:ide

addr2line -e a.out 4004e5 -f

以下所示:函数

main
/home/gordon/main.c:5

创建main.cc文件,内容以下:工具

#include <iostream>
using namespace std;

void foo()
{
    cout << "the address of foo() is " << (void*)foo << endl;
}

int main()
{
    foo();
    return 0;
}

编译main.cc:编码

g++ -g main.cc

生成a.out文件
执行a.out, ./a.out, 输出以下信息:idea

the address of foo() is 0x400896

根据输出的函数地址,使用以下命令能够查看函数名:

addr2line -e a.out 0x400896 -f

以下所示:

_Z3foov
/home/gordon/main.cc:5

能够看出C++编译器对函数名进行了编码,咱们能够在上一步命令的最后加上--demangle=gnu-v3选项,输出函数名,以下所示:

addr2line -e a.out 0x400896 -f --demangle=gnu-v3

输出的函数名以下所示:

foo()
/home/gordon/main.cc:5

Android NDK tools

当NDK生成的.so运行崩掉时,经过NDK工具查找相关信息。

ndk-stack

实时分析日志

程序运行过程当中,执行以下命令:

adb logcat | ndk-stack -sym <so文件所在路径>

当程序崩溃时,可输出崩溃信息。

先获取日志再分析

程序运行过程当中,执行以下命令:

adb logcat > 1.log

程序崩溃后,经过以下命令获取崩溃信息:

ndk-stack -sym <so文件所在路径> -dump 1.log

arm-linux-androideabi-addr2line

获取日志中关键函数指针,例如

#00 pc 00031896 /data/app/com.tools/lib/arm/libtools.so

根据地址,使用以下命令找到对应的函数:

arm-linux-androideabi-addr2line -e libtools.so 00031896 -f

参考:如何定位Android NDK开发中遇到的错误

相关文章
相关标签/搜索