2016-08-02 12 views
3

私は、関数の開始と開始にコードを自動的に追加する方法を探しています。アイデアは、後で実行コードをプロファイルしたいということです。たとえば、私は、機能を持っている:idは一意に私は私のマクロを使用するたびに与えられているcの関数の開始と終了に固有のコードを追加

void helloWorld(){ 
    printf("Function id 1 enter"); 
    printf("Hello World!\n"); 
    printf("Function id 1 exit"); 
} 

void worldHello(){ 
    printf("Function id 2 enter"); 
    printf("World hello!\n"); 
    printf("Function id 2 exit"); 
} 

void helloWorld(){ 
    printf("Hello World!\n"); 
} 

void worldHello(){ 
    printf("World hello!\n"); 
} 

私はそれらを展開されるマクロのいくつかの種類を持っていると思います。 anyoenは私がこれをどのように達成できるかについて何か良いアイデアを持っていますか?私はGCCの "__COUNTER__"を見ましたが、実際には私が望んでいたように動作しませんでした。

+3

あなたはまだgprofのに見たことが呼ばれているのですか? –

+0

関数の宣言をコードを自動的に追加するマクロ魔法に置き換えるなど、言語の基本をあまりにも酷使することは、短期間では良いアイデアのように見えるかもしれません。しかし、人々(あなた自身を含む)はあなたにそれを長期間憎むでしょう。 ;-)ここでDaveとDownvoterをSecondingし、既存のソリューションを見てみましょう。 – DevSolar

+0

いいえ、それについて知りませんでしたが、私はマイクロプロセッサ上で自分のコードを実行しています。私は、GPIOピンを使ってイネーブルされた関数のIDを設定し、別のハードウェア上で出力を読み込み、解析することを試みています。私は非常に厳しいタイミングがあり、私が通常使うプリントアウトの方法は使えません。 – Kristoffer

答えて

4

あなたはGCCを使用している場合は、-finstrument-functionsスイッチを見て - それは、基本的にどんな呼ばれる関数を入力し、去る時にユーザ定義関数を呼び出すhttps://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-finstrument-functionsを参照してください。これにはいくつかの利点があります。

  • あなたの機能をまったく変更する必要はありません。
  • あなたのコードは、関数がexittedどんなに(あなたがあなたの機能にreturnの任意の番号を持つことができますし、気にしない)
+0

これは本当に私が欲しいものをするようです! 問題は、どういうふうに関数が呼び出されたかにかかわらず、一意の固有情報をどのように作成し、本当に高速にするかです。セミホスティングは、楽観的ではありません。私はマイクロセカンドの解像度が必要で、余分なメモリがありません。 – Kristoffer

+0

あなたが必要とする固有の情報は、呼び出された関数を表すポインタである '__cyg_profile_func_enter()'の最初の引数です。今は、これらの入力/終了機能で正確に何をする必要があるかによって異なります。 –

3

番号の代わりに関数名をIDとして使用できます。関数名は一意であるためです。

#define START printf("%s:%d Start \n", __func__, __LINE__) 
#define END printf("%s:%d End \n", __func__, __LINE__) 

またはカーネルで: たとえば、あなたは、マクロを使用することができます

#define START pr_err(KBUILD_MODNAME ":%s:%d start \n", __func__, __LINE__) 
#define END pr_err(KBUILD_MODNAME ":%s:%d end\n", __func__, __LINE__) 
+0

複数のファイルには、それぞれ静的void関数(void);関数があります。関数名はソースファイル間で必ずしも一意ではありません(私はそれらが単一のファイル内にあると思いますが、その制限を避ける方法は考えられません)。 –

1

むしろ__COUNTER__よりも__func__使用することがよりわかりやすいかもしれません。ここでは、あなたが望むことをするマクロの実装例を示します。

#include <stdio.h> 

#define WRAPPED_FUNC(funcname, ...) \ 
    funcname { \ 
     printf("Function %s entered\n", __func__); \ 
     __VA_ARGS__ \ 
     printf("Function %s exited\n", __func__); \ 
    } 

WRAPPED_FUNC(
    void helloWorld(), 
    { 
     printf("Hello World!\n"); 
    } 
) 

WRAPPED_FUNC(
    void worldHello(), 
    { 
     printf("World hello!\n"); 
    } 
) 

int main() { 
    helloWorld(); 
    worldHello(); 
    return 0; 
} 
関連する問題