2010-12-21 3 views
0

C 프로그램을 실행하는 동안 만들어진 함수 호출을 기록하고 싶습니다. 아이디어는 함수 호출 기록을 만드는 것입니다. 테스트 가짜 함수가 호출되었음을 프로그램 적으로 확인할 수 있도록 이걸 원합니다. 나는 인수 또는 반환 값에 대해 상관하지 않습니다. 내가 필요가 없습니다 명시 적으로 varargs_funcptr 캐스팅 할 수 있도록 형식 정의를 만들기 위해함수 호출 추적

long longfunc0(); 
void voidfunc2(char arg0, char arg1); 

typedef void (*varargs_funcptr)(...); 
void test1() 
{ 
    varargs_funcptr function_calls[10]; 
    function_calls[0] = longfunc0; 
    function_calls[1] = voidfunc2; 
    assert(function_calls[0] == longfunc0); 
} 

가 가능 : 이상적으로 나는 이런 식으로 뭔가를보고 싶습니다?

+1

assert (function_calls [0] = longfunc0); <- 당신이 잘못 됐어 – fazo

+0

감사합니다 fazo, 코드를 업데이트했습니다 – mikelong

답변

0

올바른 방향으로 나를 가리키며 bta에게 감사드립니다. 정수를 사용하는 대신 빈 포인터를 사용하지만 솔루션은 본질적으로 동일합니다. 이 솔루션에 대해 내가 싫어하는 유일한 점은 명시 적으로 캐스팅해야한다는 것입니다.

void test1() 
{ 
    void * function_calls[10]; 
    function_calls[0] = (void *)longfunc0; 
    function_calls[0] = (void *)voidfunc2; 
    assert(function_calls[0] == ((void *)voidfunc2)); 
} 
0

당신이 좀 작은 프로젝트는 몇 가지 로깅 기능을 추가 할하려고하면 당신의 인생을

을 복잡하게하려고하는 이유를 모르겠어요 : 그것은 '작동하거나 아무튼 경우

#if defined(LOGGING) 
#define LOG(s) log(s) 
#else 
#define LOG(s) 
#endif 

void log(char *s){ 
    printf("%s"); 
    return; 
} 

void test1() 
{ 
    log("test1()\n"); 

    return; 
} 

확실하지를 작은 오류가 있지만, 당신은 아이디어를 얻을 수있다.

1

어떤 함수가 실행되었고 나중에이 포인터를 사용하지 않을 것이라면 함수 포인터를 적절한 부호없는 정수로 캐스팅하는 것이 더 쉽다. 아키텍처의 길이). 프로그램 끝의 모든 포인터를 16 진수 주소로 'printf'할 수 있으며 인수 유형이나 수량이 중요하지 않습니다.

여기서 문제는 프로그램을 실행할 때마다 함수가 정확히 동일한 메모리 주소에 있지 않을 수 있다는 것입니다. 이로 인해 어떤 함수가 어떤 포인터와 연결되는지 파악하기가 더 어려워집니다. 더 많은 메모리가 필요하지만 함수 이름의 문자열 표현을 저장하는 것이 더 나을 것입니다.

+0

이것은 흥미 롭습니다. 정확히 내가 원하는 것은 아니지만 예상되는 함수 호출에 대한 문자열 표현과 주소를 저장하고 작동 할 수있는 주소를 비교/어설 션하면됩니다. – mikelong

0

C 로그인하는 가장 쉬운 방법은 (당신이 유닉스 시스템에있는 경우) syslog.h에 정의 된 함수를 사용하는 것입니다

void closelog(void); 

void openlog(const char *ident, int logopt, int facility); 

int setlogmask(int maskpri); 

void syslog(int priority, const char *message, ...); 

void vsyslog(int priority, const char *message, va_list args); 

당신이 그 기능을 사용하면, 직접 로그를 시스템 메시지 로거 (예 : /var/log/myapplication.log)에 기록합니다.

이 파일은 많은 로그 수준을 정의합니다

LOG_EMERG 패닉 상태. 이것은 일반적으로 모든 사용자에게 브로드 캐스트됩니다.

LOG_ALERT 손상된 시스템 데이터베이스와 같이 즉시 수정해야하는 조건.

LOG_CRIT 심각한 장치 오류 등의 심각한 조건.

LOG_ERR 오류.

LOG_WARNING 경고 메시지.

LOG_NOTICE 오류 조건은 아니지만 특별히 처리해야하는 조건.

LOG_INFO 정보 메시지.

LOG_DEBUG 일반적으로 프로그램을 디버깅 할 때만 사용되는 정보가 포함 된 메시지입니다.

/* 두 번째 매개 변수는 연결이 immediatly 열립니다 syslog에 있다는 것을 의미 당신은 ID를 출력 할 것이다 : 당신은 시스템 로그를 사용하여 로그인 할 경우

예를 들어, 당신이 시도 할 수 있습니다 프로세스의 */

openlog ("syslogd", LOG_NDELAY | LOG_PID, LOG_SYSLOG);

syslog (LOG_INFO, "일부 blalblabla 문자열");

closelog();

+0

또는 자세한 내용을 찾으려면 man 3 syslog를 수행하십시오. – Dimitri