linux – 为什么gdb显示的函数地址与nm的函数地址不同?

今天,当我在 linux上调试我的代码时,我突然发现gdb中的函数地址与nm显示的不同. (可执行文件是静态链接的.)

我认为他们显示的地址应该是相同的,因为它们都是逻辑地址.但今天的发现让我感到困惑.

有人知道他们与众不同的原因吗?

我写了下面这个简单的程序来说明我遇到的情况.

void fo()              
{                      
    return ;           
}                      


void foo()             
{                      
    fo();              
}                      

int add(int a,int b)  
{                      
    foo();             
    return  a + b;     
}                      

int main()             
{                      
    int a = 1;         
    int b = 2;         
    add(a,b);         

    return 0;          
}

nm的输出是:

0000000000400584 T _Z2fov
0000000000400595 T _Z3addii
000000000040058a T _Z3foov
00000000004005b3 T main

但是当我使用gdb来调试已编译的可执行文件时,将断点放在第3行.

(gdb) bt
#0  fo () at test.cpp:4
#1  0x0000000000400593 in foo () at test.cpp:9
#2  0x00000000004005a8 in add (a=1,b=2) at test.cpp:14
#3  0x00000000004005d8 in main () at test.cpp:22

你可以看到gdb的输出与nm的输出不同.

解决方法

因为nm显示函数开始的地址,而gdb stacktrace显示函数内部执行的确切位置.确切地说,它应该是堆栈帧中的返回地址,即当堆栈中它上面的函数返回时,指向要在函数中执行的下一条指令的指针.

注意,如果你只是通过评估函数指针表达式来询问gdb的函数指针,它应该给出与nm相同的地址.

相关文章

/etc/sysctl.conf这个目录主要是配置一些系统信息,/etc/sys...
1.作用 useradd或adduser命令用来建立用户帐号和创建用户的起...
它们都是多模式编辑器,不同的是vim 是vi的升级版本,它不仅...
不管是我们在安装软件还是监测软件的使用性能,我们都要随时...
装好Tomcat7后,发现除了本机能访问外界访问不了,岂有此理。...
修改防火墙配置需要修改 /etc/sysconfig/iptables 这个文件,...