-
說明
-
功能
- 程序最前和最後添加函數調用.
-
參考
(gdb) disassemble main Dump of assembler code for function main(): 0x0000000000400567 <+0>: push %rbp 0x0000000000400568 <+1>: mov %rsp,%rbp 0x000000000040056b <+4>: push %rbx 0x000000000040056c <+5>: mov 0x8(%rbp),%rax 0x0000000000400570 <+9>: mov %rax,%rsi 0x0000000000400573 <+12>: mov $0x400567,%edi 0x0000000000400578 <+17>: callq 0x40050d <__cyg_profile_func_enter(void*, void*)> 0x000000000040057d <+22>: callq 0x40053f <show()> 0x0000000000400582 <+27>: mov $0x0,%ebx 0x0000000000400587 <+32>: mov 0x8(%rbp),%rax 0x000000000040058b <+36>: mov %rax,%rsi 0x000000000040058e <+39>: mov $0x400567,%edi 0x0000000000400593 <+44>: callq 0x400526 <__cyg_profile_func_exit(void*, void*)> 0x0000000000400598 <+49>: mov %ebx,%eax 0x000000000040059a <+51>: pop %rbx 0x000000000040059b <+52>: pop %rbp 0x000000000040059c <+53>: retq
可以看到最前和最後都添加了。
-
-
參考
-
原文
- gnu,搜索
-finstrument-functions
- gnu,搜索
-
說明
Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site. (On some platforms, __builtin_return_address does not work beyond the current function, so the call site information may not be available to the profiling functions otherwise.) void __cyg_profile_func_enter (void *this_fn, void *call_site); void __cyg_profile_func_exit (void *this_fn, void *call_site); The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table. This instrumentation is also done for functions expanded inline in other functions. The profiling calls indicate where, conceptually, the inline function is entered and exited. This means that addressable versions of such functions must be available. If all your uses of a function are expanded inline, this may mean an additional expansion of code size. If you use extern inline in your C code, an addressable version of such functions must be provided. (This is normally the case anyway, but if you get lucky and the optimizer always expands the functions inline, you might have gotten away without providing static copies.) A function may be given the attribute no_instrument_function, in which case this instrumentation is not done. This can be used, for example, for the profiling functions listed above, high-priority interrupt routines, and any functions from which the profiling functions cannot safely be called (perhaps signal handlers, if the profiling routines generate output or allocate memory)
原文 翻譯 Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site.
在函數最前和最後添加兩個統計函數調用指令 (查看上面案例)
,在進入函數和退出的函數調用,參數是上一層的函數(即被檢測函數)
,以及再上上層函數,(即被檢測函數的上層),(簡而言之就上堆棧,共三層.)
The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table.
第一個參數地址一般可以在符號表中查到對應地址。 其他 這個機制適用於 inline
,同時inline
之後會增加代碼體積.inline
還會遇到一些問題.使用 需要添加屬性來規避添加. 即這兩個函數必然需要的. 否則會造成堆棧溢出,從而導致段錯誤.
-
-
使用場景
-
普通
- 用於檢測用戶定義函數.
- 即編譯的時候添加.
-
默認
- 將給所有的用戶定義函數添加.
-
規避
-finstrument-functions-exclude-file-list=file,file,…
文件規避,files
是一個字符串,只要其是某個頭文件的子串,裏面的函數就不會添加.-finstrument-functions-exclude-function-list=sym,sym,…
,函數規避,符號是函數符號的子串也不會添加.
-
屬性規避
#define ATTR __attribute__((no_instrument_function)) void ATTR __cyg_profile_func_exit (void *this_fn,void *call_site); void ATTR __cyg_profile_func_enter (void *this_fn,void *call_site); void __cyg_profile_func_enter (void *this_fn,void *call_site) { int a=0; a++; } void __cyg_profile_func_exit (void *this_fn,void *call_site) { int b = 0; b++; } void show() { } int main() { show(); }
添加函數屬性規避給函數添加指令.
-
少數幾個使用
- 可以使用
C++
局部變量,加類的構造和析構機制實現。
- 可以使用
-
c++ 爲函數添加 hook
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.