C++ アプリケーションが実行するすべての関数呼び出しを出力する方法を誰かが知っているかどうか疑問に思っていました。システムコールだけでなく、通常の関数呼び出し、デストラクタ呼び出し、コピー構築、メソッドなども出力することを除いて、Linuxコマンドstrace
またはに似ています...ltrace
step
基本的には、GDB がスタックを印刷するときにそれを行うのと同じように、これが自動的に行われることを除いて...
-finstrument-functions
関数への入り口と出口のためのインストルメンテーション呼び出しを生成します。関数の入り口の直後と関数の出口の直前に、現在の関数のアドレスとその呼び出しサイトを使用して、次のプロファイリング関数が呼び出されます。(一部のプラットフォームで__builtin_return_address
は、現在の関数を超えて機能しないため、それ以外の場合はプロファイリング関数で呼び出しサイト情報を使用できない場合があります。)void __cyg_profile_func_enter (void *this_fn, void *call_site); void __cyg_profile_func_exit (void *this_fn, void *call_site);
最初の引数は、現在の関数の開始アドレスであり、シンボル テーブルで正確に検索できます。
このインストルメンテーションは、他の関数でインライン展開された関数に対しても行われます。プロファイリング呼び出しは、インライン関数がどこで開始され、終了されるかを概念的に示します。これは、そのような関数のアドレス可能なバージョンが利用可能でなければならないことを意味します。関数のすべての使用がインラインで展開される場合、これはコード サイズの追加の拡張を意味する場合があります。C コードで「extern inline」を使用する場合は、そのような関数のアドレス可能なバージョンを提供する必要があります。(通常はこれが当てはまりますが、運が良く、オプティマイザが常に関数をインラインで展開する場合、静的コピーを提供せずに済んだ可能性があります。)
関数に属性 no_instrument_function を指定することができます。この場合、この計測は行われません。これは、たとえば、上記のプロファイリング関数、優先度の高い割り込みルーチン、およびプロファイリング関数を安全に呼び出すことができない関数 (プロファイリング ルーチンが出力を生成するか、メモリを割り当てる場合は、おそらくシグナル ハンドラー) に使用できます。
etraceのように、すぐに使用できるツールがあります。