2010-04-08 49 views
0

我已經實現了使用gcc的-finstrument-functions選擇跟蹤行爲,這(簡化)代碼:宏給人以提供dladdr問題()

void __cyg_profile_func_enter(void *this_fn, void *call_site) 
{ 
    Dl_info di; 
    if(dladdr(this_fn, &di)) 
     printf("entered %s\n", (di.dli_sname?di_dli_sname:"<unknown>")); 
} 

這個偉大的工程,除了一兩件事:宏的處理爲好,但該功能打印出包含宏的功能的信息。

因此,包含宏的函數將其信息打印多次(這當然是不希望的)。

有什麼可以檢測到宏正在處理?或者可以根本關閉儀表宏?與sizeof()

編輯發生

PS同樣的問題:澄清:我在尋找一個解決方案,以防止宏與儀表功能(他們不應該這樣做)搞亂。不適用於跟蹤宏,函數和/或其他事物的方法。

回答

1

宏由預處理器內聯擴展,因此無法區分直接從代碼調用並從宏調用的函數。

解決此問題的唯一可能的方法是讓您的宏設置一個全局標誌,您的跟蹤函數將檢查該標誌。 這當然不是萬無一失的,因爲從宏中調用的函數所做的任何調用也會以相同的方式出現。

+0

期待預處理後的輸入,但爲什麼會出現由於宏調用'__cyg_profile_func_enter'當它們被擴大預處理器?!當應用程序正在編譯時,它們應該消失,但它看起來好像沒有消失,並且作爲一個函數行事...... – Veger 2010-04-08 17:25:48

+0

@Vegar:你能舉出一個這樣的宏的例子嗎? – Hasturkun 2010-04-08 23:14:18

+0

'#define CLEAR_REQ(reqp)memset((reqp),0,sizeof(struct raw1394_request))'例如。 – Veger 2010-04-09 07:38:19

1

如果你真的想挖掘它,你可以看到我對breakdown c++ code size的迴應。 C++模板實際上只是更正式的宏,所以這可能適用於你。

它還可能不會,因爲LINE和宏對應於呼叫者內FILE

編輯 從我的評論是:

$ gcc -E foo.c | gcc -x c-cpp-output -c -finstrument-functions - -o foo.o 

預處理管道輸送到GCC標準輸入

+0

我正在調試/追蹤包含這些宏的現有庫,並且我很困惑他們爲什麼在'__cyg_profile_func_enter'處給出匹配。爲什麼這些命令與宏使用的函數相同?我需要什麼(gcc標誌?'__cyg_profile_func_enter'函數中的一些檢測)來防止它們(不完全修改庫)。 – Veger 2010-04-08 17:30:54

+0

嘗試分離出建築物的預處理器和編譯階段。在不使用-finstrument-functions標誌的情況下預處理源文件,然後使用它編譯預處理文件。 $ gcc -E foo.c | gcc -x c -c -finstrument-functions - -o foo.o – nategoose 2010-04-08 18:29:04

+0

我一直在嘗試這個,但我似乎沒有得到這個工作。該庫正在使用libtool構建,我無法正確修改libtool調用以分別預處理這些文件。但是,感謝這個主意! – Veger 2010-04-09 07:57:08