как заставить gcc выложить отображение из потоковых графов в номера строк исходного кода - PullRequest
10 голосов
/ 30 марта 2009

Может ли gcc выложить, учитывая файл C, список всех происходящих вызовов функций с именем файла и номером строки как для самого вызова, так и для объявления функции?

Я знаю, что gcc каким-то образом сохраняет эту информацию с помощью -g (отладчики полагаются на нее) и что он может создавать дамп управляющих потоков с помощью -dr (но без имен файлов или номеров строк); но есть ли готовый инструмент, который принимает вывод gcc и выполняет то, что я хочу?

Причина, по которой я хочу, чтобы такой инструмент использовал gcc, заключается в том, что это позволит мне использовать его со стандартной системой сборки, с которой поставляется большинство программ на основе gcc (например, .configure && make), даже в тех случаях, когда инструменты, основанные на их собственный препроцессор и / или синтаксический анализатор - большая проблема, чтобы соответствовать. Я уже знаю о нескольких таких инструментах, например Ctags. Таким образом, этот вопрос является продолжением вопроса 525899 .

Ответы [ 3 ]

10 голосов
/ 30 марта 2009

Попробуйте опцию 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, которые очень легко анализировать. Циклы и условные выражения не усложняют задачу.

3 голосов
/ 11 декабря 2009

Вы можете попробовать Treehydra , плагин GCC, который дает вам доступ только для чтения к внутренним представлениям кода GCC во время компиляции. (Тем не менее, это сложная задача, и я не уверен, что она даст лучшие результаты, чем -fdump- * для этой проблемы.)

3 голосов
/ 30 марта 2009

Valgrind и KCacheGrind являются хорошим инструментом для этого использования:

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

Это даст вам файл с именем callgrind.out.pid, который вы можете открыть с помощью KCacheGrind. Это позволит вам увидеть много информации, такой как график вызовов, имя файла ...

...