"-pg"指定编译器在函数入口插入对mcount()桩函数的调用,而“-finstrument-functions”会指定编译器在函数入口插入对__cyg_profile_func_enter()函数的调用,在函数返回时插入对__cyg_profile_func_exit()函数的调用。 uftrace对这2种情况都能支持。正常情况下,c库提供了对这些桩函数的定义,所以我们链接程序时,是可以链接到c库里面的桩函数定义。
[root@localhost test]# readelf -s /lib64/libc.so.6 | grep mcount
111: 0000000000101780 91 FUNC GLOBAL DEFAULT 12 _mcount@@GLIBC_2.2.5
419: 000000000013d6a0 50 FUNC GLOBAL DEFAULT 12 _dl_mcount_wrapper_check@@GLIBC_2.2.5
1616: 000000000013d680 23 FUNC GLOBAL DEFAULT 12 _dl_mcount_wrapper@@GLIBC_2.2.5
2010: 0000000000101780 91 FUNC WEAK DEFAULT 12 mcount@@GLIBC_2.2.5
2151: 0000000000000000 0 FILE LOCAL DEFAULT ABS mcount.c
4104: 000000000013d6a0 50 FUNC LOCAL DEFAULT 12 __GI__dl_mcount_wrapper_c
4225: 0000000000100a00 335 FUNC LOCAL DEFAULT 12 __mcount_internal
6183: 0000000000101780 91 FUNC GLOBAL DEFAULT 12 _mcount
6220: 0000000000101780 91 FUNC WEAK DEFAULT 12 mcount
6721: 000000000013d680 23 FUNC GLOBAL DEFAULT 12 _dl_mcount_wrapper
7260: 000000000013d6a0 50 FUNC GLOBAL DEFAULT 12 _dl_mcount_wrapper_check
如何利用mcount桩函数:
weak类型的符号与强类型符号相同时,会被强类型符号覆盖,有相同的weak类型符号时,会被占用内存最大的weak类型符号覆盖,通过这个特性,可以利用mcount桩函数。
利用方法1:
自己编写一个带有mcount强符号的动态库并链接该库,覆盖掉标准库中符号
参数传递,可以考虑通过环境变量,文件等方式来传递