用 CodeViz 分析函数调用关系

        在之前的文章编译安装 CodeViz中讲到了如何安装 CodeViz,其实也就是如何编译打过补丁的 gcc 4.6.2。接下来就要利用编译好的工具对源代码进行函数调用方面的分析了。我们的目的是分析源代码(C,C++),生成函数调用关系图,并且在此过程中还可以根据需要进行一些配置。

  • 用打过补丁的 gcc 编译源代码
  •         这一步只要在 Makefile 中指定使用编译后的 gcc 而不是系统自带的 gcc。这样在生成目标文件的过程中编译器会把每个代码文件相应的调用关系文件输出,后缀名是 .cdepn(至少对 C 语言是这个)。当然,这里也存在一个隐患,就是不同的函数只是按照函数名来进行区分,如果有同名函数,会被当作是同一个函数。

  • 用 genfull 脚本生成全局函数调用关系信息
  •         只要在当前(包含 .cdepn 文件的)目录下执行 genfull 脚本即可,它是 CodeViz 中自带的可执行脚本,用 Perl 编写,在 CodeViz 的 bin 目录下。如下(genfull 已被加入到系统路径中,下同):

    /home/linhan/sim-sparc2   % genfull 
    Starting  pass 1: Finding input files
    Completed pass 1: 101 files found in 0 seconds
    Starting  pass 2: Reading cdepn files          
    Completed pass 2: 11123 function calls found in 0 seconds           
    Starting  pass 3: Collect identifier definitions for headers
    Completed pass 3: 290 definitions found in 0 seconds         
    Starting  pass 4: Collect identifier definitions for C/C++ files
    Completed pass 4: 0 definitions found in 0 seconds               
    Starting  pass 5: Generate reference statistics    
    Completed pass 5: 0 references to known identifiers found in 1 seconds
    Starting  pass 6: Dumping node labels                                  
    Starting  pass 7: Dumping call graph  
    Completed pass 7: Full graph dumped to file in 0 seconds
    (Pass 7)                                                 
    genfull complete: Total duration was 1 seconds
    

    在这个过程中会生成全局的调用图,默认是 full.graph。

  • 用 gengraph 脚本生成某一函数的调用关系图
  • /home/linhan/sim-sparc2   % gengraph -f ss_writeback
    /home/linhan/sim-sparc2   % ls *.ps                 
    ss_writeback.ps
    

    上述 ss_wirteback.ps 就是 ss_writeback 的函数调用关系图,ps 是默认的输出格式。除了 -f(指定分析的函数)选项,还有另外一些选项可以使用,重要的选项在下一段解释。

  • 使用选项生成更加多样的调用图
  •         gengraph 支持的选项可以通过 gengraph -h 查看,(鄙人认为)需要注意的选项有下面几个:

    -f      指定分析的函数
    -t      忽略 Linux 的内核函数
    -i      忽略 -i 之后指定的函数,用单引号包含,多个函数间用分号隔开
    -s      只显示函数名,不分析其调用情况,函数名用红色方框强调。
    -d     调用图的最大深度
    -o     指定输出文件的名字
    --output-type         输出文件的格式:ps, png, gif。默认 ps
    --output_layout      绘图的方向:LR, RL, TB, BT。默认 TB
    

    下面是一个具体的例子:

    gengraph -f sim_main -t --output-type png -o sim_main_level1.png -d 1 -i 'fprintf;printf;__builtin_fwrite;__builtin_puts' --output-layout LR -s 'ss_writeback;ss_memory;ss_execute;ss_dispatch;ss_fetch'
    

    生成的调用图如下:
    sim_main_level1

            大功告成,可喜可贺!

【本文参考】看开源代码利器—用Graphviz + CodeViz生成C/C++函数调用图(call graph)

发表评论

电子邮件地址不会被公开。 必填项已用*标注