4

今天在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的输出不同。

4

1 回答 1

6

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

请注意,如果您只是gdb通过评估函数指针表达式来请求函数指针,它应该给出与nm.

于 2013-09-25T06:20:49.470 回答