IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    跟踪c/c++代码的执行流程

    istrone发表于 2014-07-03 15:02:24
    love 0

    gcc提供了编译参数:-finstrument-functions
    可以在函数进入,离开某个函数的时候执行一个特殊的回调,这就意味着,我们可以在这个地方做一个事情。
    这两个回调如下:

    进入函数:
    void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter(void *this_func, void *call_site)

    离开函数:
    void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit(void *this_func, void *call_site)

    this_func分别对应了二进制文件的地址,十六进制。
    除此以外,还有两个程序开始和结束时候执行的函数回调:

    void main_constructor( void )
    void main_deconstructor( void )

    结合以上知识,写出自己的调试代码,然后,获取每个函数的调用过程:
    包含q_debug.h

    #define XY_DEBUG_H                                                                                                            
    
    #include 
    #include 
    
    #define DUMP(func, call)  fprintf(fp,"%s: func = %p, called by = %p\n", __FUNCTION__, func, call)
    void main_constructor( void ) __attribute__ ((no_instrument_function, constructor));
    void main_destructor( void ) __attribute__ ((no_instrument_function, destructor));
    
    #endif
    

    在你的程序里,引入以上头文件,
    对应的函数实现:

    #include"q_debug.h"                                                                            
    
    static FILE *fp;
    
    void main_constructor( void ) {
        fp = fopen( "trace.txt", "w" );
        if (fp == NULL) exit(-1);
    }
    
    void main_deconstructor( void ) {
        fclose( fp );
    }
                                                                                                                                  
    void __attribute__((__no_instrument_function__)) __cyg_profile_func_enter(void *this_func, void *call_site) {
        DUMP(this_func, call_site);
    }
    
    void __attribute__((__no_instrument_function__)) __cyg_profile_func_exit(void *this_func, void *call_site) {
        DUMP(this_func, call_site);
    }
    

    编译参数附加:-g -finstrument-functions
    mac下还需要附加:-fno-pie -g -finstrument-functions

    这样将拿到函数的十六进制地址:
    比如:__cyg_profile_func_enter: func = 0x100000d00, called by = 0x7fff8b3455fd

    地址转文件名和行数:
    mac下用:xcrun atos -o fun $l
    linux下用:addr2line -e fun $l

    其中$l是对应的十六进制地址。

    Maybe you like these:
    jquery validate 在失去焦点时执行验证代码
    运用URLClassLoader来加载外部jar包中的java类
    代码点滴
    javascript函数延迟执行
    PHP经典代码
    无觅


沪ICP备19023445号-2号
友情链接