导航

linux内核调试技巧之addr2line

Posted on 2016-12-03 22:28  Fundyqds  阅读(919)  评论(0编辑  收藏  举报

addr2line工具是一个可以将指令的地址和可执行影像转换为文件名,函数名和源代码行数的工具。这在内核执行过程中出现崩溃时,可用于快速定位出出错的位置,进而找出代码的bug。

用法

addr2line [-a| --addresses ] [-b bfdname | --target=bfdname] [-C | --demangle[=style]] [-e filename | --exe=filename] [-f | --function] [-s | --basename] [-i | --inlines] [-p | --pretty-print] [-j | --section=name] [-H | --help] [-V | --version] [addr addr ...]

参数解释

  1. -a / --addresses:在函数名、文件和行号信息之前,显示地址,以十六进制形式。
  2. -b bfdname / --target=bfdname : 指定目标文件的格式为bfdname。
  3. -c / --demangle:将低级别的符号名解码为用户级别的名字。
  4. -e filename / --exe=filename:指定需要转换地址的可执行文件名。
  5. -f / --function :在显示文件名、行号输出信息的同时显示函数名信息。
  6. -s / --basenames :仅仅显示每个文件名的基址。
  7. -i / --inlines : 如果需要转换的地址是一个内联函数,则输出的信息包括其最近范围内的一个非内联函数的信息。
  8. -j / --section :给出的地址代表指定section的偏移,而非绝对地址。
  9. -p / --pretty-print :使得该函数的输出信息更加人性化:每一个地址的信息占一行。

说明

  1. addr2line 有两种操作模式:1)十六进制地址在命令行中指定;2)十六进制地址通过标准输入指定(还没用过)
  2. 在android中addr2line工具,一般是arm-linux-androideabi-addr2line(针对arm平台)。

例子

  1. 以下是编写的一个小例子,用来展示如何使用addr2line。

源代码

#include<stdio.h>
int add(int a, int b)
{
        return a+b;
}

void main()
{
        int sum[10] = {0};
        int i;
        int array1[10] = {48, 56, 77, 33, 33, 11, 226, 544, 78, 90};
        int array2[10] = {85, 99, 66, 0x199, 393, 11, 1, 2, 3, 4}; 
        for (i=0; i<10;i++) {
                sum[i] = add(array1[i], array2[i]);
        }
}

编译命令

gcc -Wl,-Map=gdb_example.map -g -o gdb_example gdb_example.c

查找main函数的地址

grep main ./ gdb_example.map

定位

addr2line 0x0000000000400501 -e gdb_example