1、gcc参数-finstrument-functions,__cyg_profile_func_enter 函数和__cyg_profile_func_exit 函数的使用:
//#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> //#define __USE_GNU #include <dlfcn.h> __attribute__((no_instrument_function)) void __cyg_profile_func_enter (void *this_fn, void *call_site) { printf("%s,%p,called by %p\n",__func__,this_fn,call_site); } __attribute__((no_instrument_function)) void __cyg_profile_func_exit (void *this_fn, void *call_site){ printf("%s,%p,called by %p\n",__func__,this_fn,call_site); } void hello1() { printf("hello1\n"); } int main() { printf("main\n"); hello1(); return 1; }
$ gcc -finstrument-functions -o main main.c
$./main
__cyg_profile_func_enter,0x400642,called by 0x7fbe4618576d main __cyg_profile_func_enter,0x400616,called by 0x40066d hello1 __cyg_profile_func_exit,0x400616,called by 0x40066d __cyg_profile_func_exit,0x400642,called by 0x7fbe4618576d以上只是打印出了函数的调用和退出的函数地址,如果要打印出具体函数名称,可以参考
http://www.ibm.com/developerworks/cn/linux/l-graphvis/
或者参考directfb源代码中的函数调用栈打印的用法;
2、另外还可以用atexit()函数注册函数正常退出时的执行函数:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> static void my_exit(void); int main(void) { if (atexit(my_exit) != 0) printf("can't register my_exit"); printf("main is done\n"); return 0; } static void my_exit(void) { printf("Stuff print in my_exit\n"); }