如何让 gcc 输出从流程图到源代码行号的映射

发布于 2024-07-15 19:45:07 字数 469 浏览 8 评论 0原文

给定一个 C 文件,gcc 能否输出发生的所有函数调用的列表,以及调用本身和函数声明的文件名和行号?

我知道 gcc 以某种方式使用 -g 保留此信息(调试器依赖它),并且它可以使用 -dr 转储控制流图(但没有文件名或行号); 但是有没有一个现成的工具可以接受 gcc 输出并执行我想要的操作?

我希望这样的工具使用 gcc 的原因是,这将允许我将它与大多数基于 gcc 的软件附带的标准构建系统(例如 ./configure && make)一起使用,即使工具依赖于他们自己的预处理器和/或解析器是适应的一个主要麻烦。我已经知道几个这样的工具,例如ctags。 所以这个问题是 问题的后续问题525899

Can gcc spit out, given a C file, a list of the all function calls that occur, with filename and line number both for the call itself and for the function's declaration?

I know gcc somehow retains this information with -g (debuggers rely on it) and that it can dump control flow graphs with -dr (but without filenames or line numbers); but is there a ready-to-use tool that takes gcc output and does what I want?

The reason I want such a tool to use gcc is that this will allow me to use it with the standard build system most gcc-based software comes with (e.g. ./configure && make) even in cases where tools that rely on their own preprocessor and/or parser are a major hassle to fit in. I'm already aware of several such tools, e.g. ctags. So this question is a followup to question 525899.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伴我老 2024-07-22 19:45:07

尝试 gcc 选项 -fdump-tree-fixupcfg-lineno

它将以一种可以使用相对简单的词法分析器或任何正则表达式引擎轻松解析的方式“漂亮地打印”解析 AST(带有行号)。 只需找到所有以 '=' 开头且后跟 '(' 的非关键字 - 这将是函数调用。

所有复杂的表达式将被分成几行,因此一行中不会出现两个函数调用。

以简单的程序为例:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define PI (3.1415926536)

int main(int argc, char *argv[]) {
    double  angle = PI / 2.0;
    printf("Sine = %lf, cosine = %lf\n", sin(angle), cos(angle));
    return EXIT_SUCCESS;
}

编译它使用 -fdump-tree-fixupcfg-lineno ,你会得到这样的结果:

main (argc, argv)
{
  double angle;
  int D.3381;
  double D.3380;
  double D.3379;

  # BLOCK 2, starting at line 8
  # PRED: ENTRY (fallthru)
  [test.c : 8] angle = 1.57079632680000003119857865385711193084716796875e+0;
  [test.c : 9] D.3379 = [test.c : 9] cos (angle);
  [test.c : 9] D.3380 = [test.c : 9] sin (angle);
  [test.c : 9] printf (&"Sine = %lf, cosine = %lf\n"[0], D.3380, D.3379);
  [test.c : 10] D.3381 = 0;
  return D.3381;
  # SUCC: EXIT

}

你不会得到任何复杂的表达式 - 只有赋值和函数调用,没有 CPP 宏,非常容易解析循环和条件。不要让事情变得更加困难。

Try gcc option -fdump-tree-fixupcfg-lineno.

It will "pretty print" parsing AST (with line numbers) in a way that can easily be parsed using relatively simple lexer or any regex engine. Just find all non-keywords preceded by '=' and followed by '(' - it will be function calls.

All complex expressions will be split into several lines so no two function calls will appear on one line.

Take simple program:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define PI (3.1415926536)

int main(int argc, char *argv[]) {
    double  angle = PI / 2.0;
    printf("Sine = %lf, cosine = %lf\n", sin(angle), cos(angle));
    return EXIT_SUCCESS;
}

Compile it with -fdump-tree-fixupcfg-lineno and you get something like this:

main (argc, argv)
{
  double angle;
  int D.3381;
  double D.3380;
  double D.3379;

  # BLOCK 2, starting at line 8
  # PRED: ENTRY (fallthru)
  [test.c : 8] angle = 1.57079632680000003119857865385711193084716796875e+0;
  [test.c : 9] D.3379 = [test.c : 9] cos (angle);
  [test.c : 9] D.3380 = [test.c : 9] sin (angle);
  [test.c : 9] printf (&"Sine = %lf, cosine = %lf\n"[0], D.3380, D.3379);
  [test.c : 10] D.3381 = 0;
  return D.3381;
  # SUCC: EXIT

}

You won't get any complex expressions - just assignments and function call and no CPP macros, very easy to parse. Loops and conditionals don't make it much more difficult.

轻许诺言 2024-07-22 19:45:07

Valgrind 和 KCacheGrind 似乎是一个很好的工具:

valgrind --tool=callgrind --dump-instr=yes ./your_binary

这将为您提供一个名为 callgrind.out.pid 的文件,您可以使用 KCacheGrind 打开该文件。 这会让你看到很多信息,比如调用图、文件名......

Valgrind and KCacheGrind seems a good tool for this use :

valgrind --tool=callgrind --dump-instr=yes ./your_binary

This will give you a file called callgrind.out.pid that you can open with KCacheGrind. This will let you see lots of informations like call graph, filename ...

若言繁花未落 2024-07-22 19:45:07

您可以尝试 TreeHydra,这是一个 GCC 插件,可让您对 GCC 内部表示进行只读访问编译期间的代码。 (但是,构建起来有点麻烦,而且我不确定对于这个问题它会比 -fdump-* 提供更好的结果。)

You might try Treehydra, a GCC plugin that gives you read-only access to GCC internal representations of code during compilation. (However, it's a bit of a chore to build, and I'm not sure it'll give better results than -fdump-* for this problem.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文