2012-09-21 128 views
1

我想用gcc選項-finstrument-functions來獲取函數的程序調用堆棧。__cyg_profile_func_enter和g ++ 2.95.4

典型代碼

void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function)); 
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function)); 
int depth = -1; 

void __cyg_profile_func_enter (void *func, void *caller) 
{ } 

void __cyg_profile_func_exit (void *func, void *caller) 
{ } 

int main() 
{ 
printf("Hello world"); 
return 0 
} 

用gcc -finstrument-功能test.c的

運行./a.out,和一切ok編譯。

但是當我用g ++做到這一點時,我得到了對__cyg_profile_func_enter函數的未定義引用。我讀過它的發生是因爲_cyg函數是C代碼的一部分,如果我想在C++中使用它們,我應該使用extern「C」,因此會有最終代碼。

extern "C"{ 
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function)); 
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function)); 
int depth = -1; 

void __cyg_profile_func_enter (void *func, void *caller) 
{ } 

void __cyg_profile_func_exit (void *func, void *caller) 
{ } 
} 
int main() 
{ 
printf("Hello world"); 
return 0 
} 

它編譯使用g ++ -finstrument函數test.c的,然後試着去執行它,但得到的核心轉儲錯誤消息。我使用gdb跟蹤轉儲,並且__cyg_profile_func_enter()中存在分段錯誤。

GCC版本是2.95.4。我也在4.4.3上測試過,一切正常。那麼是否有任何可能性使用2.95.4 gcc來解決這個問題?

+0

您是否設法使用C++,手頭的任何解決方案? – cross

回答

3

gcc 2.95.4已超過十年。我設法挖出一個......並編譯你的東西。它顯然不識別__attribute__((no_instrument_function)),因爲生成的彙編代碼有:

__cyg_profile_func_enter: 
.LFB1: 
     pushl %ebp 
.LCFI0: 
     movl %esp,%ebp 
.LCFI1: 
     subl $8,%esp 
.LCFI2: 
     movl 4(%ebp),%eax 
     addl $-8,%esp 
     pushl %eax 
     pushl $__cyg_profile_func_enter 
.LCFI3: 
     call __cyg_profile_func_enter 
     movl 4(%ebp),%eax 
     addl $16,%esp 
     addl $-8,%esp 
     pushl %eax 
     pushl $__cyg_profile_func_enter 
     call __cyg_profile_func_exit 
     movl %ebp,%esp 
     popl %ebp 
     ret
因此,它遞歸調用自身,當然這以堆棧溢出結束。

如果你真的需要兩個GCC 2.95.x(面向天堂,滾動的眼睛,畏縮在臉上,看起來「爲什麼啊,爲什麼???」)-finstrument-functions,那麼你就必須讓他們「真正extern」 - 即把它們放在一個單獨的源文件中,你可以編譯而不需要這個選項,並在以後連接它。

+0

有沒有官方的.4版本?這個味道有點像2.96,在任何理智的代碼中所有的希望都失去了...... – PlasmaHH

+0

所以g ++ 2.95.4(它真的很老)的主要問題是沒有像no_instrument_function這樣的選項嗎? –

+0

@John Square:我不認爲_that_是一個特殊的問題;一方面,它似乎隻影響C++編譯器('g ++'),並且可以通過編譯C代碼('gcc')和/或沒有'-finstrument-functions'選項來解決。 gcc/g ++ 2.9x還有其他問題,我寧願不處理,關於語言標準/功能......它已經過時了,你說。 @PlasmaHH:我用2.95.3來編譯上面,因爲我找不到2.95.4。 –

3

即使使用gcc 4.4.3,no_instrument_functions在所有情況下都不能正常工作。如果函數內聯,那麼即使設置了no_instrument_functions屬性,也會將檢測調用添加到該函數中。即使-finstrument-functions-exclude-file-list也不起作用。

使其可靠工作的唯一方法是將跟蹤代碼放入另一個文件中,並在不使用-finstrument-functions的情況下編譯此文件。

+0

是的,我這樣做,它的工作原理。將__cyg_profile_func_enter(exit)放入另一個文件中,使其來自共享庫。所以如果我想使用我的fins-function代碼,我只需使用-finstrument-functions重新編譯需要的代碼並鏈接我的庫 –