当前位置:  开发笔记 > 编程语言 > 正文

获取图片函数的工具调用代码图

如何解决《获取图片函数的工具调用代码图》经验,为你挑选了6个好方法。

我有一个很大的工作空间,有许多C代码的源文件.虽然我可以使用Object浏览器看到从MS VS2005中的函数调用的函数,但是在MSVC 6.0中,这只显示了在非图形显示中从特定函数调用的函数.另外,它没有显示从say开始调用的函数main(),然后是从它调用的函数,依此类推,更深入到叶级函数内部.

我需要一个工具,它会给我一个功能调用图,用图形表示功能callee,caller用箭头或类似的东西连接,从main()最后一级功能开始,或者至少在一个C源文件中以图形方式显示所有功能的调用图.如果我能打印这张图表会很棒.

任何好的工具(不一定是免费的工具)?



1> philant..:

埃及(免费软件)

NCC

KcacheGrind(GPL)

Graphviz(CPL)

CodeViz(GPL)


我刚试过埃及.它的图形太可怕了.我不确定其他人.

2> Ciro Santill..:

动态分析方法

在这里,我将介绍一些动态分析方法.

动态方法实际运行程序以确定调用图.

与动态方法相反的是静态方法,它试图在不运行程序的情况下单独从源中确定它.

动态方法的优点:

捕获函数指针和虚拟C++调用.这些在任何非平凡的软件中都有大量存在.

动态方法的缺点:

你必须运行程序,这可能很慢,或者需要你没有的设置,例如交叉编译

只显示实际调用的函数.例如,根据命令行参数,可以调用或不调用某些函数.

KcacheGrind

https://kcachegrind.github.io/html/Home.html

测试程序:

int f2(int i) { return i + 2; }
int f1(int i) { return f2(2) + i + 1; }
int f0(int i) { return f1(1) + f2(2); }
int pointed(int i) { return i; }
int not_called(int i) { return 0; }

int main(int argc, char **argv) {
    int (*f)(int);
    f0(1);
    f1(1);
    f = pointed;
    if (argc == 1)
        f(1);
    if (argc == 2)
        not_called(1);
    return 0;
}

用法:

sudo apt-get install -y kcachegrind valgrind

# Compile the program as usual, no special flags.
gcc -ggdb3 -O0 -o main -std=c99 main.c

# Generate a callgrind.out. file.
valgrind --tool=callgrind ./main

# Open a GUI tool to visualize callgrind data.
kcachegrind callgrind.out.1234

您现在处于一个非常棒的GUI程序中,其中包含许多有趣的性能数据.

在右下角,选择"调用图"选项卡.这会显示一个交互式调用图,当您单击这些函数时,它会与其他窗口中的性能指标相关联.

要导出图形,请右键单击它并选择"导出图形".导出的PNG如下所示:

从那我们可以看出:

根节点是_start实际的ELF入口点,并包含glibc初始化样板

f0,f1并按照f2彼此的预期进行调用

pointed也显示了,即使我们用函数指针调用它.如果我们传递了命令行参数,它可能没有被调用.

not_called 未显示,因为它没有在运行中被调用,因为我们没有传递额外的命令行参数.

很酷的valgrind是它不需要任何特殊的编译选项.

因此,即使您没有源代码,也只能使用可执行文件,您可以使用它.

valgrind 通过轻量级"虚拟机"运行代码,设法做到这一点.

在Ubuntu 18.04上测试过.

gcc -finstrument-functions + etrace

https://github.com/elcritch/etrace

-finstrument-functions 添加回调,etrace解析ELF文件并实现所有回调.

不幸的是,我无法让它工作:为什么`-finstrument-functions`对我不起作用?

声明的输出格式为:

\-- main
|   \-- Crumble_make_apple_crumble
|   |   \-- Crumble_buy_stuff
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   \-- Crumble_prepare_apples
|   |   |   \-- Crumble_skin_and_dice
|   |   \-- Crumble_mix
|   |   \-- Crumble_finalize
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_put
|   |   \-- Crumble_cook
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_bake

除了特定的硬件跟踪支持之外,它可能是最有效的方法,但是您必须重新编译代码.


请注意,动态调用图仅涵盖程序的一次运行.

3> MattK..:

理解在创建调用图方面做得非常好.



4> Ira Baxter..:

我们的DMS软件再造工具包具有静态控制/数据流/点对/调用图分析,已应用于大型系统(~~ 2500万行)的C代码,并生成此类调用图,包括通过函数指针调用的函数.



5> 小智..:

您可以尝试使用CScope + tceetree + Graphviz.



6> 小智..:

你可以在这里查看我的基于bash的C调用树生成器.它允许您指定一个或多个您想要调用者和/或被调用信息的C函数,或者您可以指定一组函数并确定连接它们的函数调用的可达性图...即告诉我所有方式main( ),foo()和bar()是连接的.它使用graphviz/dot作为图形引擎.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有