programing

발신자 기능의 이름은 어떻게 알 수 있습니까?

oldcodes 2023. 10. 6. 21:58
반응형

발신자 기능의 이름은 어떻게 알 수 있습니까?

C 로__FUNCTION__현재 함수의 이름을 가져오는 데 사용할 수 있습니다.그러나 a()라는 이름의 함수를 정의하면 다음과 같이 b()로 불립니다.

b()
{
    a();
}

이제, 소스 코드에는 a()를 호출하는 b()와 같은 많은 함수가 있습니다. 예를 들어 c(), d(), e()...

a() 내에서 a()를 호출한 함수의 이름을 탐지하기 위한 코드를 추가할 수 있습니까?

추가:

  1. 오해의 소지가 있는 오타를 죄송합니다.수정했습니다.
  2. 디버깅을 위해 어떤 함수가 a()를 호출하는지 알아보려고 합니다.나는 당신이 같은 상황일 때 어떻게 하는지 모릅니다?
  3. 그리고 제 코드는 vxWorks 아래에 있지만 C99와 관련된 것인지 아니면 다른 것인지 잘 모르겠습니다.

오직 a에서만 할 수 있는 일은 없습니다.

그러나 간단한 표준 매크로 트릭을 사용하면 원하는 것을 달성할 수 있습니다. IIUC는 발신자의 이름을 보여줍니다.

void a()
{
    /* Your code */
}

void a_special( char const * caller_name )
{
    printf( "a was called from %s", caller_name );
    a();
}

#define a() a_special(__func__)

void b()
{
    a();
}

gcc 내장으로 가능합니다.

void * __builtin_return_address(int level)

다음 방법으로 함수 a()의 즉시 호출자를 인쇄해야 합니다.

예:

a() {
    printf ("Caller name: %pS\n", __builtin_return_address(0));
}

, backtrace()기능.

자세한 내용과 코드 예시는 맨 페이지를 참조하십시오.

시도해 보기:

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__ 만약 다른 C99 컴파일러를 하는 경우른 C99한다면 GCC다로 도?).__func__.

참조: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html

역추적은 스레드에서 현재 활성화되어 있는 함수 호출의 목록입니다.프로그램의 역추적을 검사하는 일반적인 방법은 gdb와 같은 외부 디버거를 사용하는 것입니다.그러나 로깅이나 진단 등의 목적으로 프로그램 내에서 프로그래밍 방식으로 역추적을 얻는 것이 유용한 경우도 있습니다.

헤더 파일 execinfo.h는 현재 스레드의 역추적을 얻고 조작하는 세 가지 함수를 선언합니다.

난 하여 /를 수 .__func__로그/debug 기능의 이름을 지정하지만 이를 호출하는 기능의 이름을 지정합니다.

는 않습니다.__func__하지만 "feel"는 함수를 사용하는 것을 좋아할 것입니다.

예.

#define LOG(s, data...) log("%s: "s, __function__, ## data)

플랫폼이 Windows(윈도우)인 경우 다음을 사용할 수 있습니다. 콜스택 걷기

a()를 호출하는 각 함수에 매개 변수로 전달되는 정수 식별자를 태그로 지정한 다음 a()switch-case construct를 사용하여 어떤 함수가 a()를 호출했는지 알 수 있습니다.printf()는 정수 식별자 값에 따라 어떤 함수가 a()를 호출하는지 알려줍니다. 만약 그것을 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");
}

}

문제의 함수가 다른 c파일이면 가능합니다.

#define name_of_function(...) \
    printf("Function %s is parent\n", __FUNCTION__); \
    name_of_function(__VA_ARGS__);

그리고 파일의 맨 위에 살고 있습니다.

#ifdef name_of_function
#undef name_of_function
#endif

같은 파일에 있는 경우 두 번째 매크로에서 함수 정의를 랩핑한 다음 첫 번째 매크로를 마지막에 다시 정의할 수 있습니다.다른 정의에서 새로운 정의를 생성할 수 없기 때문에 확장성이 아주 좋지는 않지만, 특정 기능에 대해 부모를 추적하려는 경우에는 말도 안 되는 소리 없이 작동합니다.

https://godbolt.org/z/f2jKOm

원래 함수의 포장지로 다른 C 함수를 사용합니다. 즉, 디버그하는 것은 원래 함수의 반환 데이터를 억제하는 것을 의미합니다.또는 포장지와 원래 기능의 반환 유형을 동기화해야 합니다.

타이핑 동기화를 방지하려면 여기에 제시된 대로 C 매크로를 사용해야 합니다.

/* You need to debug the function foo().
 * So rename foo() to foo_debug() in source and header files.
 * Then define a macro named foo().
 *
 * Benefits:
 *   - you don't have to care about the return type
 *     of the original function;
 *   - C-macro is inline solution -- there are not
 *     extra calls in the backtrace.
 */

/* Function which is to debug after renaming. */
type_t foo_debug();

#define foo() \
    ({                                                       \
        fprintf(stderr, "[DEBUG] %s:%d %s() called by %s\n", \
                __FILE__, __LINE__, "foo", __FUNCTION__);    \
        foo_debug();                                         \
    })

또는 C-마크로 한 줄:

#define foo() (fprintf(stderr, "[DEBUG] %s:%d %s() called by %s\n", __FILE__, __LINE__, "foo", __FUNCTION__), foo_debug())
#include <stdio.h>
#include <stdlib.h>

#define FECTION_NAME(FECTION) printf("FECTION=%s \r\n", #FECTION);

int a() {
  printf("A function call");
}

int b() {
  printf("B function call");
}

int main(){
FUNCTION_NAME(a);
FUNCTION_NAME(b);
return 0;

}

언급URL : https://stackoverflow.com/questions/16100090/how-can-we-know-the-caller-functions-name

반응형