LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

应用异常定位:通过记录maps更加准确定位问题点

关键词:coredump、maps、objdump、gdb等等。

最近遇到一个应用异常问题定位(Floating point exception/SIGFPE),说明是一个算术运算异常。

这种问题通常也比较简单:通过ulimit -c打开coredump;SIGFPE会触发coredump;然后gdb分析coredump文件即可。

这里的目的是记录一下过程,以及过程中做的一些优化点。主要就是增加了记录maps,更准确定位问题点。

 

1. 设置coredump

将coredump文件输出到/tmp目录下:

echo "/tmp/core-%e-%p" > /proc/sys/kernel/core_pattern

打开coredump选项:

ulimit -c unlimited

在系统遇到异常之后,就可能在/tmp/core-<comm>-<pid>文件。

2. 程序中记录maps信息

coredump文件中的backtrace能精确到函数,然后给一个发生问题的确切地址。

但是这个地址是在进程中的虚拟地址,这个地址和可执行文件的对应关系,需要maps来确定。

所以如果在程序开始记录自身的maps信息,能更有效定位问题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>

#define SELF_MAPS "/proc/self/maps"
void dump_self_maps(void)
{
    FILE *self_fd, *output_fd;
    char buf[1024], output_name[32], process_name[16];

    memset(buf, 0x0, sizeof(buf));
    memset(output_name, 0x0, sizeof(output_name));

    prctl(PR_GET_NAME, process_name);

    snprintf(output_name, sizeof(output_name), "/tmp/maps_%s_%d.txt", process_name, getpid());
    self_fd=fopen(SELF_MAPS,"r");
    if(self_fd==NULL)
    {
        perror("open file");
        exit(0);
    }

    output_fd=fopen(output_name,"w");
    if(output_fd==NULL)
    {
        perror("open file");
        exit(0);
    }

    while(fgets(buf,sizeof(buf),self_fd)!=NULL)
    {
        fputs(buf,output_fd);
        //printf("%s", buf);
    }

    fclose(output_fd);
    fclose(self_fd);
}

void main(void)
{
    dump_self_maps();
}

就会生成/tmp/maps-<comm>-<pid>.txt文件,通过pid可以和core文件匹配上。

3. 定位实例

定位过程如下记录。

3.1 执行程序

执行程序后发现如下异常:

Floating point exception

这个信息说明收到了信号SIGFPE,是一种算术运算错误。

3.2 查看coredump文件

sudo gdb <bin> <core>

然后查看backtrace信息:

从#2可以看出是div0错误,然后最接近的是#3,说明问题出在IFMS_USBHostSend()中。

但是在IFMS_USBHostSend()函数哪里呢?

3.3 结合maps查看最直接问题点

如果想看到更直接的问题点,就需要通过maps信息来确定。

首先看地址0xb6bb4a12,看其落在maps的那个区域:

可以看出这个地址在libusb230.so中,然后计算偏移量:

0xb6bb4a12 - 0xb6bb0000 = 0x4a12

所以最直接问题点在libusb230.so文件的0x4a12处。

通过objdump -d <bin/lib>,然后找到地址0x4a12:

通过反汇编结果可以看出问题点在__aeabi_uidivmod()函数。结合代码就不难发现问底根源了。 

 

posted on 2019-12-31 00:00  ArnoldLu  阅读(1356)  评论(0编辑  收藏  举报

导航