Analisando fluxo de execução com o cflow
- por Sergio Prado
Identificar o fluxo de execução de uma aplicação é fácil usando a ferramenta cflow do projeto GNU.
A partir do código-fonte de uma aplicação, a ferramenta é capaz de encontrar e exibir o fluxo de execução completo da aplicação de forma hierárquica e intuitiva, e pode facilitar bastante nosso trabalho, principalmente quando precisamos analisar um código mais complexo que não seja de nossa autoria.
O uso da ferrramenta é bem simples. Dado o código-fonte da aplicação:
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <stdio.h> int show(const char *str, int times) { printf("Message: %s\n", str); } int main(int argc, const char *argv[]) { show("Hello!", 0); return 0; } |
Basta rodar o cflow sobre ele:
$ cflow main.c main() <int main (int argc, const char *argv[]) at main.c:8>: show() <int show (const char *str, int times) at main.c:3>: printf() |
Dá para ter uma noção melhor da utilidade da ferramenta em um código-fonte maior ou mais complexo. No exemplo abaixo, estou executando o cflow no código-fonte do comando wc:
$ cflow wc.c main() <int main (int argc, char **argv) at wc.c:127>: errf() <void errf (char *fmt, ...) at wc.c:34>: va_start() error_print() <void error_print (int perr, char *fmt, va_list ap) at wc.c:22>: vfprintf() perror() fprintf() exit() va_end() counter() <void counter (char *file) at wc.c:108>: fopen() perrf() <void perrf (char *fmt, ...) at wc.c:46>: va_start() error_print() <void error_print (int perr, char *fmt, va_list ap) at wc.c:22>: vfprintf() perror() fprintf() exit() va_end() getword() <int getword (FILE *fp) at wc.c:78>: feof() getc() isword() <int isword (unsigned char c) at wc.c:64>: isalpha() COUNT() fclose() report() <void report (char *file, count_t ccount, count_t wcount, count_t lcount) at wc.c:57>: printf() report() <void report (char *file, count_t ccount, count_t wcount, count_t lcount) at wc.c:57>: printf() |
Com o auxílio das ferramentas cflow2dot e dot, é possível gerar uma versão gráfica do fluxo de execução:
$ cflow --format=posix --omit-arguments --level-indent='0=\t' --level-indent='1=\t' --level-indent=start='\t' wc.c | cflow2dot | dot -Tjpg -o wc.dot && eog wc.dot |
A ferramenta tem algumas deficiências, como não lidar muito bem com ponteiros de função e chamadas condicionais, mas pode ajudar bastante em situações específicas de análise de código.
À propósito, é possível conseguir um resultado parecido com o plugin CCTree do Vim:
Happy hacking!
Sergio Prado
Sem Comentários
Nenhum comentário até agora... é a sua chance de ser o primeiro a comentar!