1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| chunli@blog:~/source/function_tree/gcc$ cat fun_tree.c #define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h>
int offset = 0; FILE *report = NULL;
void __attribute__((__no_instrument_function__)) print_space(int n) { int i = 0; for(i = 0; i < n; i++) { fprintf(report, " "); } }
void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter(void *this_func, void *call_site) { print_space(offset);
Dl_info info; if (dladdr(this_func, &info)) { const char *sname = info.dli_sname; fprintf(report, "+ %s\n", sname); } offset+=4; }
void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit(void *this_func, void *call_site) { offset-=4; print_space(offset); Dl_info info; if (dladdr(this_func, &info)) { const char *sname = info.dli_sname; fprintf(report, "- %s\n", sname); }
}
void __attribute__((constructor)) __attribute__((__no_instrument_function__)) before_main() { report = fopen("report.log", "w+"); }
void __attribute__((destructor)) __attribute__((__no_instrument_function__)) after_main() { fclose(report); }
// gcc -O0 -rdynamic -finstrument-functions fun_tree.c xxx.c -ldl && ./a.out chunli@blog:~/source/function_tree/gcc$
|