2

C で記述された DBMS、主に postgres バイナリでいくつかのプロファイルを実行しようとしています。ユーティリティを使用して、プログラムによって行われた一連の関数呼び出しを出力できるようにしたいと考えています。簡単な例として、次のプログラムを取り上げます。

void func1 () { 
  printf("x\n");
}

void func2 () {
  printf("y\n");
  func1();
}

int main () {
  func2();
  func1();
  return 0;
}

この「ユーティリティ」でコンパイルして実行すると、次のようになります。

-> main
  -> func2
    -> func1
  -> func1
<- 

また、ソース コードもメイクファイルも変更できませんが、-g既に有効になっています。

過去にこれと同様のことを行うプロファイラーを使用したことは知っていますが、どのプロファイラーか思い出せません。私はいくつかのグーグルを行いましたが、ソースまたはメイクファイルを変更する必要のない適切な解決策を見つけることができませんでした.

これを達成するためにどのプロファイリング ツールを使用できますか? それとも存在しないのですか?

ありがとう。

4

2 に答える 2

1

これを直接実行するツールはありませんが、GDB ブレークポイント コマンドを使用してスタック トレースを取得し、正規表現ブレークを使用して、関心のある関数をブレークすることができます。その時点で、それを後処理して、希望の形式で出力します。

たとえば、次のようなことができます (簡潔にするために編集されています)。

$ gdb ./program
(gdb) rbreak program.c:.
...
(gdb) commands
>silent
>bt
>cont
>end
(gdb) run
...
#0  main () at program.c:22
...
#0  foo (number=113383) at program.c:4
#1  main () at program.c:22
...
Program exited normally.
(gdb)
于 2013-08-31T03:20:25.737 に答える
0

あなたが望むのは「トレース」です。「すべての」関数の入口と出口がファイルに記録されます。これは、私が知っているいくつかのインタープリター言語で提供されていますが、コンパイルされた言語では提供されていません。これを行うプロファイラーは知りません。

「すべて」を引用したのは、I/O、メモリの割り当て、解放など、あなたが望んでいないと思われる関数呼び出しの巨大なレイヤーがあるためです。実際、ほとんどすべての機械語命令は、実際にはCPUチップのマイクロコードまたは内部機能。私はあなたがそれらを見るのを気にしないと思います:)

最も小さなプログラムを除いて、そのようなトレースは人間が読むには長すぎます。あなたが本当に求めているのは、時間に関してプログラムが何をしているかを理解することであるなら、その主題は非常に議論されてきました.これは私の貢献です.

于 2013-08-31T14:40:04.970 に答える