1

クラスのコンストラクターがそのオブジェクトを初期化する方法を調べる必要があります。

私が持っているコンストラクターの動作に関する重要な情報は次のとおりです。

  1. コンストラクターは、オブジェクトの vtable を埋めます。
  2. コンストラクターには名前がないため、関数ポインターはありません。

次のようなコードを書くにはどうすればよいですか。

  1. コンストラクターのアドレスを取得しますか?
  2. オブジェクトの初期化をトレースしますか?

前もって感謝します。

4

2 に答える 2

2

コンストラクターのアドレスを取得するためのより良い方法は、ラッパー テンプレート関数を記述しnew(C++11 の完全転送では 1 つだけ必要です)、そのアドレスを取得することです。

于 2012-08-11T05:54:13.817 に答える
1
  1. コンストラクターのアドレスを取得しますか?

残念ながら、これはプラットフォーム固有であり、アセンブリ言語を使用する必要があります。使用できる基本的な手法は、呼び出し元からの次の命令のアドレスを返す関数を呼び出すことです。そこから、コンパイラによって生成されたコンストラクターのアセンブリ言語ソース コードを調べることで、メモリ内のコンストラクター コードの実際のアドレスを特定できます。アイデアは、関数が呼び出されるアドレスを確認し、そのアドレスから、コンストラクター関数を構成する以前のコマンドによって使用されたバイト数を差し引くことです。アセンブリ言語ソースを使用する必要があるのは、元の C++ コードから機械語コマンドのメモリ フットプリントを判断できないためです。前述のように、これはプラットフォームとコンパイラに大きく依存します。

たとえば、x86_64 では、次のようにして呼び出し元の次の命令のアドレスを取得できます。

get_next_instruction_address.h

extern "C" unsigned long get_return_address();

get_next_instruction_address.S

.section .text

.global get_next_instruction_address

get_next_instruction_address:
    movq (%rsp), %rax
    ret

を呼び出すget_next_instruction_address()と、返される値は、関数呼び出しが完了した後の (アセンブリ内の) 次の命令の値になります。コンストラクターのアセンブリ コードで関数呼び出しが行われる場所を使用すると、コンストラクターの開始のアドレスの値が何であるかをバックトラックして確認できます。

于 2012-08-11T05:42:29.323 に答える