2010-12-21 72 views
0

我想记录执行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?

+1

assert(function_calls [0] = longfunc0); < - 你说错了 – fazo 2010-12-21 14:11:35

+0

谢谢fazo,我已经更新了代码 – mikelong 2010-12-21 14:15:00

回答

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

不知道是否有用,或者没有按” t有小错误,但你有想法

1

如果你只是记录哪些函数运行,你不会在以后使用这些指针,可能更容易将函数指针转换为无符号整数(适当的长度为您的建筑)。您仍然可以将程序结尾处的所有指针作为十六进制地址进行“打印”,并且参数类型或数量是什么都没有关系。

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

+0

这很有趣。这不是我正在寻找的东西,但是如果我要为预期的函数调用存储字符串表示形式和地址,并且只是比较/断言它可以工作的地址。 – mikelong 2010-12-21 14:31:28

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日志,你可以试试这个:

/*第二个参数是指 连接到系统日志会打开 立刻和你将打印ID 的过程。 */

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

syslog(LOG_INFO,“Some blalblabla string”);

closelog();