跟踪功能调用

时间:2010-12-21 14:07:31

标签: c function-pointers typedef

我想记录在执行C程序期间进行的函数调用。这个想法是创建一个函数调用历史记录。我想这样,所以我可以编程验证测试假函数是否被调用。我不关心参数或返回值。理想情况下,我希望它看起来像这样:

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);
}

是否可以创建一个typedef,以便我不需要显式地转换为varargs_funcptr?

4 个答案:

答案 0 :(得分:1)

如果您只记录运行了哪些函数,并且稍后不会使用这些指针,则可能更容易将函数指针强制转换为无符号整数(适用于您的体系结构的长度)。您仍然可以将程序末尾的所有指针“打印”为十六进制地址,并且参数类型或数量无关紧要。

这里的问题是每次运行程序时,您的函数可能不会位于完全相同的内存地址。这使得更难以确定哪个函数与哪个指针一起使用。它将需要更多内存,但您可能更幸运存储函数名称的字符串表示。

答案 1 :(得分: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;
}

不确定它是否有效或没有小错误,但你明白了

答案 2 :(得分:0)

登录C的最简单方法是使用syslog.h中定义的函数(如果你在Unix系统中):

 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包含通常仅在调试程序时使用的信息的消息。

例如,如果您想使用syslog进行日志记录,可以尝试:

  

/ *第二个参数意味着   将打开与syslog的连接   立即打印你的身份证   过程   * /

     

openlog(“syslogd”,LOG_NDELAY | LOG_PID,LOG_SYSLOG);

     

syslog(LOG_INFO,“some blalblabla string”);

     

closelog();

答案 3 :(得分:0)

感谢bta让我指向正确的方向。我使用void指针代替使用整数,但解决方案基本相同。关于这个解决方案我唯一不喜欢的是必须明确地施放。

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