1

gccオプション-finstrument-functionsを使用して、プログラムの関数の呼び出しスタックを取得したいと思います。

典型的なコード

void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
int depth = -1;

void __cyg_profile_func_enter (void *func,  void *caller)
{    }

void __cyg_profile_func_exit (void *func, void *caller)
{    }

int main()
{
printf("Hello world");
return 0
}

gcc-finstrument-functionstest.cを使用してコンパイルします

./a.outを実行し、すべてOKです。

しかし、g ++でそれを行ったとき、__cyg_profile_func_enter関数への未定義の参照を取得しました。_cyg関数はCコードの一部であり、C ++で使用する場合は、extern "C"を使用する必要があるため、最終的なコードがあります。

extern "C"{
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
int depth = -1;

void __cyg_profile_func_enter (void *func,  void *caller)
{    }

void __cyg_profile_func_exit (void *func, void *caller)
{    }
}
int main()
{
printf("Hello world");
return 0
}

g ++ -finstrument-functions test.cでコンパイルし、実行しようとしましたが、コアダンプされたエラーメッセージが表示されました。gdbでダンプをトレースしましたが、__ cyg_profile_func_enter()でセグメンテーション違反が発生しました。

GCCバージョンは2.95.4です。また、4.4.3とすべてOKでテストしました。では、2.95.4 gccを使用してこの問題を回避する可能性はありますか?

4

2 に答える 2

4

gcc 2.95.4 は 10 年以上前のものです。私はなんとか1つを掘り出し...そしてあなたのものをコンパイルしました。__attribute__((no_instrument_function))生成されたアセンブリ コードには次のものがあるため、 明らかに認識されません。

__cyg_profile_func_enter:
.LFB1:
        pushl %ebp
.LCFI0:
        movl %esp,%ebp
.LCFI1:
        subl $8,%esp
.LCFI2:
        movl 4(%ebp),%eax
        addl $-8,%esp
        pushl %eax
        pushl $__cyg_profile_func_enter
.LCFI3:
        call __cyg_profile_func_enter
        movl 4(%ebp),%eax
        addl $16,%esp
        addl $-8,%esp
        pushl %eax
        pushl $__cyg_profile_func_enter
        call __cyg_profile_func_exit
        movl %ebp,%esp
        popl %ebp
        ret
そのため、再帰的に自分自身を呼び出し、もちろんスタック オーバーフローで終了します。

本当に両方の gcc 2.95.x が必要な場合 (天を向いて、目を転がし、顔をしかめる、「なぜああ、なぜ ???」) -finstrument-functionsそれらを「真に」作成する必要があります。externつまり、それらを別のソースファイルに入れます。オプションなしでコンパイルし、後でリンクします。

于 2012-09-21T10:57:38.183 に答える
3

gcc 4.4.3 でも、no_instrument_functions はすべての場合に正しく機能するとは限りません。関数がインライン化されている場合、no_instrument_functions 属性が設定されていても、インストルメンテーション呼び出しが関数に追加されます。-finstrument-functions-exclude-file-list でも機能しません。

確実に動作させる唯一の方法は、トレース コードを別のファイルに入れ、このファイルを -finstrument-functions なしでコンパイルすることです。

于 2012-12-28T15:33:21.310 に答える