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アドレスを表示するため、 stacktraceは関数で実行が正確にどこで進行したかを示します。正確には、スタックフレーム内のリターンアドレスである必要があります。これは、スタック内のその上の関数が戻るときに、関数内で実行される次の命令へのポインターです。gdb

gdb関数ポインタ式を評価して関数ポインタを求めるだけの場合は、 と同じアドレスを与える必要があることに注意してくださいnm

于 2013-09-25T06:20:49.470 に答える