1

backtrace() を使用して、トレース目的で関数アドレスを取得したいと考えています。実行時に backtrace() から関数アドレスを保存し、後で分析に使用したい (たとえば、関数名をロードバックし、dladdr() を使用して呼び出し統計などを調べる)。それをしている間、私はクラスメンバー関数の静的アドレスを見ようとしていました.

Alib.so、ああ:

class A
{
public:
    void print_addr();
};

A.cpp

#include "A.h"
#include <iostream>

void A::print_addr()
{
   std::cout << (void*)&A::print_addr << std::endl;
}

main.cpp

#include <iostream>
#include "Alib/A.h"

int main()
{
   std::cout << (void*) &A::print_addr << std::endl;
   // if put the line below, with the line above, output is the same
   // It seems whenever the code pull in &A::print_addr into main, addr is 
   // always the same.  Only different if print .so itself
   // A a; a.print_address();
   return;
}

これは以下を出力します:

0x400870

メインを複数回再実行すると、同じアドレスが返されます。main.cpp を次のように変更すると:

int main()
{
   A a;
   a.print_addr();
   return 0;
}

.so または main を再コンパイルしなくても、main 実行可能ファイルを実行するたびに出力が異なります。

0x7fae48524aa0

これをチェックしている理由は、backtrace() を使用して現在のスタック関数の関数情報 (アドレス) をトレース用に取得したいためであり、非常によく似た動作をします。.so ライブラリ関数内で backtrace() を呼び出し、現在のスタック関数で backtrace() と dladdr() を使用して関数のシンボル情報を取得しようとしました。関数アドレスを .so に出力するのと main で出力すると、異なるアドレスが得られます。dladdr() の関数アドレスを使用して、シンボル名などの情報を取得するにはどうすればよいですか?

.so と main() で異なる方法でマップされたクラス メンバー関数アドレスに何かありますか?

編集:問題を説明するために、言葉を変えてより多くのコード例を挙げてください。

4

0 に答える 0