2013-09-24 91 views
4

今天,當我在linux上調試我的代碼時,我突然發現gdb中的函數地址與nm顯示的不同。 (可執行文件是靜態鏈接的。)爲什麼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;   
}     

納米輸出爲:

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的輸出。

回答

6

由於nm顯示啓動功能的的地址,而gdb堆棧跟蹤示出的確切位置的執行已經進展內部的功能。準確地說,它應該是堆棧幀中的返回地址,即當函數在堆棧中的函數返回時,指向要在函數中執行的下一條指令的指針。

請注意,如果您只是通過評估函數指針表達式來請求函數指針gdb,它應該給出與nm相同的地址。

+0

啊哈!而已!非常感謝。 – Alex

+2

除非二進制文件在加載等時重新定位,等等。 – Vatine

+0

@Vatine,你能說更多嗎?二進制重定位會影響符號地址嗎? – Alex

相關問題