2010-12-21 40 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();