我正在 Unix/Linux 平台上寻找这样一种工具,它可以实现:
例如:
#include <stdio.h>
int square(int x) { return x*x; }
int main(void) {
square(2);
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个程序时,它会打印出来
我知道在gdb某种程度上可以做到这一点,或者valgrind他们都没有完全按照我的意愿去做。我只是想知道是否存在这样的工具?谢谢。
要让可执行文件在被调用时打印函数名称,在 GNU 系统上,您可以使用gcc's-finstrument-functions选项并将dladdr()地址转换为函数名称。
创建一个instrument.c喜欢:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#define TRACE_FD 3
void __cyg_profile_func_enter (void *, void *)
__attribute__((no_instrument_function));
void __cyg_profile_func_enter (void *func, void *caller)
{
static FILE* trace = NULL;
Dl_info info;
if (trace == NULL) {
trace = fdopen(TRACE_FD, "w");
if (trace == NULL) abort();
setbuf(trace, NULL);
}
if (dladdr(func, &info))
fprintf (trace, "%p [%s] %s\n",
func,
info.dli_fname ? info.dli_fname : "?",
info.dli_sname ? info.dli_sname : "?");
}
Run Code Online (Sandbox Code Playgroud)
然后将您的可执行文件编译为:
$ gcc -O0 -rdynamic -finstrument-functions square.c instrument.c -ldl
$ ./a.out 3>&1
0x400a8f [./a.out] main
0x400a4f [./a.out] square
Run Code Online (Sandbox Code Playgroud)
(此处使用 fd 3 转储函数名称以使其与 stdout 和 stderr 流分开)。
dli_sname如果您只需要函数名称,您可以调整代码以仅打印。
使用gcov:
$ gcc -O0 --coverage square.c
$ ./a.out
$ gcov -i square.c
$ awk -F '[,:]' '$1 == "function" && $3 > 0 {print $3, $4}' square.c.gcov
1 square
1 main
Run Code Online (Sandbox Code Playgroud)
(其中数字是函数被调用的次数(我们跳过部分中从未调用$3 > 0过的次数awk))。
这通常用于代码覆盖率(正在测试多少代码)。您还可以使用gprof代码分析工具(通常用于计算在代码的各个区域花费了多少时间):
$ gcc -O0 -pg square.c
$ ./a.out
$ gprof -b -P
Call graph
granularity: each sample hit covers 2 byte(s) no time propagated
index % time self children called name
0.00 0.00 1/1 main [7]
[1] 0.0 0.00 0.00 1 square [1]
-----------------------------------------------
Index by function name
[1] square
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2661 次 |
| 最近记录: |