Análise Estática com LLVM

2010 June 2
by Pedro Kiefer

LLVM é uma coleção de tecnologias de compiladores (ou algo assim, é que eles usam para se autodefinir), mas esse não é o ponto mais interessante – apesar de existirem diversos subprojetos bastante interessantes, a parte mais legal do LLVM é o subprojeto Clang Static Analyzer – ok, ele é parte do subprojeto Clang na verdade. O Clang utiliza as tecnologias oferecidas pelo LLVM para implementar um compilador completo, com algumas vantagens é extremamente rápido e dá ótimas mensagens de erro.

Meu interessante por análise estática surgiu primeiro quando eu ainda brincava de descompilar programas e entender o que eles faziam, afinal, quando se lê um código sem executá-lo estamos fazendo uma análise. Mas cansei de ler ASM, passei a programar mais e fui atrás de algo que fizesse algo parecido com o que eu fazia. Descobri várias ferramentas que fazem algum tipo de análise estática: lint, sparse e o clang. Sim, lint aquele programa velhão que verificava se um código C era bem formado fazia nada mais do que uma análise estática do código – ok, sem grandes interpretações do que o código fazia. O Sparse é um parser semântico para C, faz mais ou menos a mesma coisa que o lint fazia, mas é um código mais novo, originalmente escrito pelo Linus Torvalds. E finalmente há o Clang…

Clang Static Analyzer

Primeiro passo para testar e usar o Clang é obter os arquivos fonte e compilá-lo, pelo menos não achei uma versão para download (ok, há uma versão para Mac OSX). Há um bom passo-a-passo aqui. Em linhas gerais:

cd tools
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ..
./configure
make
make install

Atualmente o Clang não instala os scripts scan-build e scan-view, então é necessário copiá-los manualmente. Instalei os scripts em $HOME/bin/, pois já tinha esse caminho no meu path. scan-build é a ferramenta responsável por criar o ambiente necessário para executar o Clang. Com a ferramenta instalada é hora de utilizá-la!

Ah, ele também tem um suporte bem legal a Objective-C, tanto para programas para Mac quanto para aplicativos de iPhone / iPad! Mas, ainda não testei essa funcionalidade.

Usando o Clang

Precisamos de um código com alguns problemas para testar o clang. Resolvi reutilizar o código do post sobre valgrind. Ok, não é o melhor código para demonstrar as funcionalidades do clang, mas é suficientemente bom. Há quatro bugs naquele código, todos foram corretamente identificados pelo valgrind. Quantos desses erros o Clang conseguirá identificar? Usando o scan-build, habilitando verificações experimentais, obtemos:

pedro@urubu:~/code$ scan-build --experimental-checks gcc -g -O1 -o valtest valtest.c
valtest.c:13:2: warning: Access out-of-bound array element (buffer overflow)
        x[5] = 'a';
        ^~~~
valtest.c:20:2: warning: Value stored to 'x' is never read
        x = malloc(5 * sizeof(char));
        ^   ~~~~~~~~~~~~~~~~~~~~~~~~
valtest.c:20:4: warning: Allocated memory never released. Potential memory leak.
        x = malloc(5 * sizeof(char));
        ~~^~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
scan-build: 3 bugs found.
scan-build: Run 'scan-view /tmp/scan-build-2010-06-01-4' to examine bug reports.

Dentro de /tmp/scan-build-2010-06-01-4 há um relatório em html com cada erro encontrado, basicamente o código fonte anotado. Um dos erros acima gerou o seguinte relatório:

clang-report

Exemplo de relatório gerado

Resultado, o Clang encontrou três problemas no código, sendo que dois são na mesma linha de código – gerados pelo mesmo problema. Então dos quatro bugs existentes no código a ferramenta identificou dois… nada mal para uma ferramenta que só analizou o código fonte! Claro, há outros bugs que a ferramenta irá identificar e o valgrind não. There is no silver bullet, mas várias ferramentas utilizadas em conjunto conseguem aumentar bastante a qualidade do código escrito.

Duas coisas para terminar este post, não utilizei o clang para gerar código, somente para fazer análise do código fonte, mas isso é perfeitamente viável. E para completar, se formos utilizar o Clang junto a um projeto com autotools, fariamos:

pedro@urubu:~/code/myproject$ scan-build ./configure
pedro@urubu:~/code/myproject$ scan-build make
No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

Bad Behavior has blocked 68 access attempts in the last 7 days.