一起talk C栗子吧(第一百二十五回:C语言实例--显示文件名和行号)

各位看官们,大家好,上一回中咱们说的内置宏的例子,这一回咱们说的例子是:显示文件名和行号。闲话休提,言归正转。让我们一起talk C栗子吧!

我们在上一回中通过内置宏来显示文件名和行号。这一回,我们介绍另外一个显示文件名和行号的方法:使用addr2line这个工具来显示文件名行号。

addr2line是一个调试工具,主要借助可执行文件中的调试信息,把某个地址转换为程序中的文件名或者行号。该工具有多个选项,我们常用的选项是”e”和”f”。

  • 例如:addr2line -e a.out 0x12345678 会显示与0x12345678这个地址相对应的文件名和行号。
  • 例如:addr2line -f -e a.out 0x12345678 会在原来的基础上显示与0x12345678这个地址相对应的函数名,当然了这两个选项可以一起使用,这样就可以同时显示文件名,函数名和行号。

看官们,光说不练不是我们的风格,我们举一个实际的例子,通过代码来说明如何使用addr2line这个工具来显示文件名和行号。

在例子中,我们首先运行func函数,然后在主函数中显示函数func的地址。

int main()
{
    func();
    printf("address of func:%p \n",func);

    return 0;
}

函数func的定义如下,简单起见,我们只在该函数中输出一行语句,表示函数中运行。

void func()
{
    printf("func is running \n");
}

我们编译该程序,并且加入调试信息,具体的命令如下:

gcc -g Ex082_addr2line.c -o s      //编译生成名叫s的可执行文件

运行该文件,可以得到以下结果:

 ./s                       //运行该可执行文件
func is running    
address of func:0x804844d  //显示了函数的地址

接着我们通过地址来查看文件名,行号和函数名,具体的命令如下:

addr2line -f -e s 0x804844d     //同时使用f和e选项,注意f需要基于e来运行,所以f在e前面
func                            //显示与地址0x804844d对应的函数名
/home/talk8/Ex082_addr2line.c:8 //显示与地址0x804844d对应的文件名和行号

看官们,正文中就不写代码了,完成的代码放到了我的资源中,大家可以点击这里下载使用。从代码中可
以看到func函数位于文件中的第8行。

最后我们来对比一下这两种显示文件名和行号方法的优缺点:

  • 内置宏的优点:在程序运行时就能直接显示出文件名和行号,不需要调试和其它第三方工具。
  • 内置宏的缺点:需要在运行的程序中提前加入内置宏,否则不会显示文件名和行号,此外,在程序中的哪 一行添加内置宏也是头疼的事情,这个需要依据程序的需要来添加。
  • addr2line工具的优点:在调试程序的时候,通过某个地址直接显示文件名和行号(地址通常在dump文 件获取),最重要的是我们不需要在代码中添加任何内容。
  • addr2line工具的缺点:需要在编译时使用gcc的”g”选项来加入调试信息,这会增加编译时间并且使目标文件的变大。此外,它需要使用程序中的地址才能显示文件名和行号,如果没有一个有效的地址,那么 它就无能为力了,正所谓巧妇难为无米之炊嘛。

依据我的经验来看,显示文件名和行号主要是为快速找出程序中的错误。如果程序中的错误比较容易重现,那么可以在程序中必要的地方提前加入内置宏,然后编译,并且运行编译后的程序。当重现错误时就会直接输出文件名和行号。这样就能快速定位到错误发生的文件和错误在文件中的位置。反之,如果程序中的错误不容易重现,那么就可以使用addr2line这个工具了。当程序发生错误时,生成dump文件(杧核心转储文件),在该文件中找到错误发生时的地址,使用该工具就可以得到发生错误的文件和错误在文件中的具体位置。另外,如果没有dump文件时,可以使用gdb进行调试,然后借助gdb的info命令查看相关函数的地址(该内容,我们在一百二十三回中介绍过,如果忘记了,可以点击这里查看前面章回的内容)。

看官们,在实际工作中,我们写的程序会发生各种各样的错误。因此,希望大能够自己动手熟练掌握这两种显示文件名和行号的方法 。并且结合我分享的经验在不同的情况中使用不同的方法,快速地找出程序中的错误。

各位看官,关于显示文件名和行号的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。

你可能感兴趣的:(addr2line,显示行号,显示文件名)