36

C 言語では、現在の関数の名前__FUNCTION__を取得するために使用できます。しかし、a() という名前の関数を定義し、以下のように b() で呼び出された場合:

b()
{
    a();
}

さて、ソースコードには、c()、d()、e() など、a() を呼び出す b() のような関数がたくさんあります。

a() 内に、a() を呼び出した関数の名前を検出するコードを追加することは可能ですか?

さらに遠く:

  1. 誤解を招くタイプミスで申し訳ありません。私はそれを修正しました。
  2. デバッグ目的で a() を呼び出す関数を見つけようとしています。同じ状況になったらどうするかわかりませんか?
  3. また、私のコードは vxWorks の下にありますが、それが C99 に関連しているのか、それとも何か他のものに関連しているのかはわかりません。
4

10 に答える 10

10

Linux システムを使用している場合は、このbacktrace()機能を使用できます。

詳細とコード例については、man ページを参照してください。

于 2013-04-19T08:22:11.897 に答える
9

これを試して:

void a(<all param declarations to a()>);

#ifdef DEBUG
#  define a(<all params to a()>) a_debug(<all params a()>, __FUNCTION__)
void a_debug(<all params to a()>, const char * calledby);
#endif

void b(void)
{
  a(<all values to a()>);
}

#ifdef DEBUG
#  undef a
#endif

void a(<all param declarations to a()>)
{
  printf("'%s' called\n", __FUNCTION__);
}

#ifdef DEBUG
void a_debug(<all param declarations to a()>, const char * calledby)
{
  printf("'%s' calledby '%s'", __FUNCTION__, calledby);
  a(<all params to a()>);
}
#endif

たとえば の<all param declarations to a()>場合int i, double d, void * p<all params to a()>ですi, d, p


または(悪意は少ない;->>-ただし、 a() への呼び出しごとに変更する必要があるため、コードの改造が増えます):

void a((<all params of normal a()>    
#ifdef DEBUG
  , const char * calledby
#endif
  );

void a((<all params of normal a()>    
#ifdef DEBUG
  , const char * calledby
#endif
  )
{
#ifdef DEBUG
  printf("'%s' calledby '%s', __FUNCTION__, calledby);
#endif
  ...
}

...

void b(void)
{
    a(<all params of normal a()>
#ifdef DEBUG
      , __FUNC__
#endif
    );
}

__FUNCTION__は GCC で利用できます (少なくとも?)。別の C99 コンパイラを使用している場合は、に置き換え__func__ます。

于 2013-04-19T08:15:52.147 に答える
3

参照: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

バックトレースは、スレッドで現在アクティブな関数呼び出しのリストです。プログラムのバックトレースを検査する通常の方法は、gdb などの外部デバッガーを使用することです。ただし、ロギングや診断などの目的で、プログラム内からプログラムでバックトレースを取得すると便利な場合があります。

ヘッダー ファイル execinfo.h は、現在のスレッドのバックトレースを取得して操作する 3 つの関数を宣言します。

于 2015-04-21T06:02:05.823 に答える
0

a()を呼び出す各関数に、パラメーターとしてa()に渡される整数識別子をタグ付けし、 a()で大文字と小文字の切り替え構造を使用して、どの関数がa () .A printf()を呼び出したかを伝えることができます 。 a()の switch-case コンストラクトへの引数としてそれを使用する場合、整数識別子の値に応じて、 どの関数がa()を呼び出したかがわかります

#include<stdio.h>

void a(int);
void b();
void c();
void d();

int main(void)
{

b();
c();
d();

}

void b()
{

int x=1;
a(x);

}

void c()
{

int x=2;
a(x);

}

void d()
{

int x=3;
a(x);

}

void a(int x)
{

switch(x)
{
case 1:
printf("b called me\n");
break;
 case 2:
printf("c called me\n");
break;
case 3:
printf("d called me\n");
}

}
于 2013-04-19T08:14:12.347 に答える