Function Trace

函数跟踪

__cyg_profile_func_enter__cyg_profile_func_exit 是用于函数调用追踪的特殊函数。当你使用 -finstrument-functions编译选项时,编译器会在每个函数的开始和结束处插入这两个函数. 这样,你可以实现函数调用的检测和分析。

这里是一个简单的例子,首先我们有一个用于跟踪函数的 func_trace.c 文件:

#include <stdio.h>

static FILE *fp_trace;

void __attribute__((constructor)) traceBegin(void) {
    fp_trace = fopen("func_trace.out", "w");
}

void __attribute__((destructor)) traceEnd(void) {
    if (fp_trace != NULL) {
        fclose(fp_trace);
    }
}

void __cyg_profile_func_enter(void *func, void *caller) {
    if (fp_trace != NULL) {
        fprintf(fp_trace, "entry %p %p\n", func, caller);
    }
}

void __cyg_profile_func_exit(void *func, void *caller) {
    if (fp_trace != NULL) {
        fprintf(fp_trace, "exit %p %p\n", func, caller);
    }
}

然后,我们编写一个简单的测试代码 main.c

#include <stdio.h>

int foo(void) {
    return 2;
}

int bar(void) {
    zoo();
    return 1;
}

void zoo(void) {
    foo();
}

int main(int argc, char **argv) {
    bar();
}

接下来,将 main.cfunc_trace.o 一起编译,并加上 -finstrument-functions 选项:

gcc main.c func_trace.o -finstrument-functions

运行 ./a.out,就会产生 func_trace.out 文件,其中记录了函数调用的信息。你可以使用 addr2line 命令来查看函数名:

addr2line -f -e ./a.out $ADDRESS

这样,你就可以得到函数调用关系。如果想进一步处理这些跟踪数据,可以使用工具如 graphviz 来创建可视化的调用关系图。

自动化单元测试

print_parameter

call_test_func

xml

results matching ""

    No results matching ""