-
说明
-
功能
- 程序最前和最后添加函数调用.
-
参考
(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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.