Análise estática - da data à integração

Cansado de revisões ou depurações de código intermináveis, às vezes você se pergunta como simplificar sua vida. E tendo procurado um pouco, ou tropeçado por acaso, você pode ver a frase mágica: "Análise estática". Vamos ver o que é e como pode interagir com o seu projeto.



Evolução

Na verdade, se você escreve em qualquer linguagem moderna, então, mesmo sem perceber, você passa por um analisador estático. O fato é que qualquer compilador moderno fornece um pequeno conjunto de avisos sobre possíveis problemas no código. Por exemplo, ao compilar o código C ++ no Visual Studio, você pode ver o seguinte:



problemas

Nesta saída, vemos que a variável var nunca foi usada em qualquer lugar da função. Então, na verdade, você quase sempre usou um analisador de código estático simples. No entanto, ao contrário de analisadores profissionais como Coverity, Klocwork ou PVS-Studio, os avisos fornecidos pelo compilador podem indicar apenas uma pequena gama de problemas.



Se você não sabe ao certo o que é análise estática e como implementá-la, leia este artigo para saber mais sobre essa metodologia.



Por que a análise estática é necessária?



Resumindo: aceleração e simplificação.



A análise estática permite que você encontre muitos problemas diferentes em seu código: do uso indevido de construções de linguagem a erros de digitação. Por exemplo, em vez de



auto x = obj.x;
auto y = obj.y;
auto z = obj.z;


Você escreveu o seguinte código:



auto x = obj.x;
auto y = obj.y;
auto z = obj.y;


Como você pode ver, há um erro de digitação na última linha. Por exemplo, PVS-Studio emite o seguinte aviso:



V537 Considere revisar a exatidão do uso do item 'y'.



Se você quiser colocar suas mãos neste erro, tente um exemplo pronto no Compiler Explorer: * clique em *.



E como você entende, nem sempre é possível prestar atenção a essas partes do código imediatamente e por isso você pode sentar para depurar por uma boa hora, imaginando por que tudo funciona tão estranhamente.



No entanto, este é um erro claro. E se o desenvolvedor escreveu um código abaixo do ideal devido ao fato de que ele se esqueceu de algumas sutilezas da linguagem? Ou até mesmo permitido um comportamento indefinido no código? Infelizmente, esses casos são completamente comuns, e a maior parte do tempo é gasta depurando código de trabalho específico que contém erros de digitação, erros típicos ou comportamento indefinido.



É para essas situações que surge a análise estática. Este é um assistente para o desenvolvedor que apontará vários problemas no código e explicará na documentação porque não é necessário escrever desta forma, a que isso pode levar e como corrigi-lo. Aqui está um exemplo de como pode ser: * clique *.



Você pode encontrar erros mais interessantes que o analisador pode detectar nos artigos:



  • Os 10 principais erros em projetos C ++ em 2019
  • Os 10 principais erros em projetos C # de 2019
  • Os 10 principais bugs em projetos Java de 2019


Agora, depois de ler este material e convencido da utilidade da análise estática, você pode colocá-la à prova. Mas por onde você começa? Como faço para integrar uma nova ferramenta em um projeto em andamento? E como apresentar a equipe a ele? Você encontrará respostas para essas perguntas abaixo.



Nota. A análise estática não substitui ou nega algo tão útil como revisões de código. Ele complementa esse processo ajudando a detectar e corrigir erros de digitação, imprecisões e construções perigosas com antecedência. É muito mais produtivo focar nos algoritmos e na compreensão do código ao revisar o código, em vez de procurar o parêntese errado ou ler funções de comparação chatas .



0. Conhecendo o instrumento



Tudo começa com uma versão de teste. Na verdade, é difícil decidir implementar algo no processo de desenvolvimento se você nunca viu a ferramenta ao vivo antes. Portanto, o primeiro passo é baixar a versão de teste .



O que você aprenderá nesta fase:



  • Quais são as formas de interagir com o analisador;
  • O analisador é compatível com seu ambiente de desenvolvimento;
  • Que problemas existem em seus projetos agora.


Depois de instalar tudo o que você precisa, a primeira coisa a fazer é executar uma análise de todo o projeto ( Windows , Linux , macOS ). No caso do PVS-Studio no Visual Studio, você verá uma imagem semelhante:



Lista

O ponto é que geralmente os analisadores estáticos emitem um grande número de avisos para projetos com uma grande base de código. Não há necessidade de consertar todos eles, pois seu projeto já está funcionando, o que significa que esses problemas não são críticos. No entanto, você pode ver os avisos mais interessantese corrija-os, se necessário. Para fazer isso, você precisa filtrar a saída e deixar apenas as mensagens mais confiáveis. No plug-in PVS-Studio para Visual Studio, isso é feito filtrando por níveis de erro e categorias. Para obter a saída mais precisa, deixe apenas Alto e Geral habilitados :



Lista

Na verdade, 178 avisos são muito mais fáceis de visualizar do que alguns milhares ... Avisos bons são freqüentemente encontrados nas



guias Médio e Baixo , mas essas categorias incluem os diagnósticos que têm menor precisão (confiabilidade). Mais informações sobre níveis de aviso e opções para trabalhar no Windows podem ser encontradas aqui: * clique *.



Depois de revisar com sucesso os erros mais interessantes (e corrigi-los com sucesso), vale a pena suprimir os avisos restantes . Isso é para garantir que novos avisos não se percam entre os antigos. Além disso, um analisador estático é um ajudante do programador, não uma lista de bugs. :)



1. Automação



Após a reunião, é hora de configurar os plug-ins e integrá-los ao CI. Isso deve ser feito antes que os programadores comecem a usar o analisador estático. A questão é que um programador pode esquecer de ativar a análise ou simplesmente não deseja fazê-lo. Para fazer isso, você precisa fazer uma verificação final de tudo, para que o código não verificado não possa entrar no ramo de desenvolvimento geral.



O que você aprenderá nesta fase:



  • Quais opções de automação a ferramenta oferece;
  • O analisador é compatível com seu sistema de compilação?


Como não há documentação perfeita, às vezes você precisa escrever para o suporte . Isso é bom e ficaremos felizes em ajudá-lo. :)



Agora vamos descer aos serviços de integração contínua (CI). Qualquer analisador pode ser embutido neles sem maiores problemas. Para fazer isso, você precisa criar um estágio separado no pipeline, que geralmente é encontrado após a montagem e os testes de unidade. Isso é feito usando vários utilitários de console. Por exemplo, PVS-Studio fornece os seguintes utilitários:



  • PVS-Studio_Cmd.exe (análise de soluções, projetos C #, C ++ no Windows)
  • CLMonitor.exe (monitoramento de compilação)
  • pvs-studio-analyser (análise de projetos C ++ em Linux / macOS)
  • pvs-studio-dotnet (análise de soluções, projetos C # em Linux / macOS)
  • pvs-studio.jar (análise de projetos Java)
  • PlogConverter (conversor de arquivo de log)


Para integrar a análise ao CI, você precisa fazer três coisas:



  • Instale o analisador;
  • Análise de execução;
  • Entregar resultados.


Por exemplo, para instalar o PVS-Studio no Linux (Debian-base), você precisa executar os seguintes comandos:



wget -q -O - https://files.viva64.com/etc/pubkey.txt \
    | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list \
  https://files.viva64.com/etc/viva64.list
  
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio


Em sistemas Windows, não é possível instalar o analisador a partir do gerenciador de pacotes, mas é possível implantar o analisador a partir da linha de comando:



PVS-Studio_setup.exe /verysilent /suppressmsgboxes 
/norestart /nocloseapplications


Você pode ler mais sobre como implantar PVS-Studio em sistemas Windows * aqui *.



Após a instalação, você precisa executar a análise diretamente. No entanto, é recomendável fazer isso somente após a compilação e os testes terem passado. Isso ocorre porque a análise estática geralmente leva o dobro do tempo da compilação.



Como o método de inicialização depende da plataforma e das especificações do projeto, mostrarei a opção C ++ (Linux) como exemplo:



pvs-studio-analyzer analyze -j8 \
                            -o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w


O primeiro comando fará a análise e o segundo converterá o relatório em formato de texto, exibirá na tela e retornará um código de retorno diferente de 0 em caso de avisos. Um mecanismo semelhante é útil para bloquear um assembly na presença de mensagens de erro. No entanto, você sempre pode remover o sinalizador -w e não bloquear a montagem que contém os avisos.



Nota. O formato do texto é inconveniente. É apenas um exemplo. Preste atenção ao formato de relatório mais interessante - FullHtml. Ele permite que você navegue pelo seu código.



Você pode ler mais sobre como configurar a análise em CI no artigo " PVS-Studio e integração contínua " (Windows) ou " Como configurar PVS-Studio no Travis CI"(Linux).



Ok, você configura o analisador no servidor de compilação. Agora, se alguém carregou o código não verificado, o estágio de verificação cairá e você poderá encontrar o problema, mas isso não é muito conveniente, pois é mais eficiente verificar o projeto não depois como os branches foram mesclados e, antes disso, no estágio de solicitação de pull.



Em geral, a configuração da análise de uma solicitação de pull não difere muito do lançamento normal da análise em CI. Exceto pela necessidade de obter uma lista de arquivos alterados. Normalmente, eles podem ser obtidos solicitando a diferença entre branches usando git:



git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list


Agora você precisa passar esta lista de arquivos para o analisador. Por exemplo, no PVS-Studio, isso é implementado usando a sinalização -S :



pvs-studio-analyzer analyze -j8 \
                            -o PVS-Studio.log \
                            -S .pvs-pr.list


Você pode aprender mais sobre a análise de solicitações pull * aqui *. Mesmo que o seu IC não esteja na lista de serviços especificada no artigo, a seção geral sobre a teoria desse tipo de análise será útil para você.



Ao configurar a análise de solicitações pull, você pode bloquear confirmações contendo avisos, criando assim um limite que o código não verificado não pode cruzar.



Tudo isso é muito bom, mas gostaria de poder ver todos os avisos em um só lugar. Não apenas de um analisador estático, mas também de testes de unidade ou de um analisador dinâmico. Existem vários serviços e plug-ins para isso. O PVS-Studio, por exemplo, possui um plugin para integração com o SonarQube .



2. Integração nas máquinas dos desenvolvedores



Agora é hora de instalar e configurar o analisador para uso diário de desenvolvimento. Neste ponto, você já se familiarizou com a maioria das formas de trabalhar, então essa pode ser chamada de a parte mais fácil.



Como a opção mais simples, os desenvolvedores podem instalar o analisador necessário. No entanto, isso levará muito tempo e os distrairá do desenvolvimento, portanto, você pode automatizar esse processo usando o instalador e os sinalizadores necessários. Existem vários sinalizadores para PVS-Studio para instalação automatizada . No entanto, sempre existem gerenciadores de pacotes como Chocolatey (Windows), Homebrew (macOS) ou dezenas de opções para Linux.



Em seguida, você precisará instalar os plug-ins necessários, por exemplo, para Visual Studio , IDEA ,Rider etc.



3. Uso diário



Nesse estágio, é hora de dizer algumas palavras sobre as formas de acelerar o desempenho do analisador no uso diário. Uma análise completa de todo o projeto leva muito tempo, mas com que frequência alteramos o código de uma vez em todo o projeto? Dificilmente existe uma refatoração em tão grande escala que afetará imediatamente toda a base de código. O número de arquivos alterados por vez raramente ultrapassa dez, portanto, faz sentido analisá-los. Para tal, existe um modo de análise incremental . Só não se assuste, esta não é outra ferramenta. Este é um modo especial que permite que você analise apenas os arquivos alterados e suas dependências, e isso acontece automaticamente após a construção, se você estiver trabalhando no IDE com o plugin instalado.



Se o analisador detectar problemas no código alterado recentemente, ele o relatará por conta própria. Por exemplo, PVS-Studio irá informá-lo sobre isso usando uma notificação:



notificação

Nem é preciso dizer que não é suficiente dizer aos desenvolvedores para usarem a ferramenta. Precisamos de alguma forma dizer a eles o que é e como é. Por exemplo, aqui estão artigos sobre início rápido para PVS-Studio, mas você pode encontrar tutoriais semelhantes para qualquer ferramenta de sua preferência:



  • Como executar o PVS-Studio no Windows (C, C ++, C #)
  • Como executar PVS-Studio em Linux e macOS (C, C ++)
  • Como iniciar o PVS-Studio Java


Esses artigos fornecem todas as informações necessárias para o uso diário e não levam muito tempo. :)



Mesmo na fase de conhecer a ferramenta, suprimimos muitos avisos durante um dos primeiros lançamentos. Infelizmente, os analisadores estáticos não são perfeitos, então eles dão falsos positivos de vez em quando. Geralmente é fácil suprimi-los, por exemplo, no plugin PVS-Studio para Visual Studio, basta clicar em um botão:



suprimir

No entanto, você não pode apenas suprimi-los. Por exemplo, você pode relatar um problema ao suporte. Se for possível corrigir falsos positivos, então, em atualizações futuras, você poderá notar que, cada vez, há cada vez menos falsos positivos específicos para sua base de código.



Depois da integração



Então, passamos por todos os estágios de integração da análise estática ao processo de desenvolvimento. Apesar da importância de configurar tais ferramentas em CI, o computador do desenvolvedor é o lugar mais importante para começar. Afinal, um analisador estático não é um juiz que diz em algum lugar longe de você que o código é inútil. Pelo contrário, é um assistente que avisa se você está cansado e lembra se você se esqueceu de algo.



No entanto, sem o uso regular, é improvável que a análise estática simplifique muito o desenvolvimento. Afinal, seu benefício mais importante para o desenvolvedor não reside tanto em encontrar seções de código complexas e controversas, mas em sua detecção precoce. Concorde que não é apenas desagradável, mas também muito demorado, encontrar um problema quando as edições vão para o teste. A análise estática, quando usada regularmente, analisa cada alteração diretamente no seu computador e relata lugares suspeitos enquanto trabalha no código.



E se você ou seus colegas ainda não têm certeza se vale a pena implementar o analisador, sugiro que prossiga com a leitura do artigo " Razões para implementar o analisador de código estático PVS-Studio no processo de desenvolvimento". Ele aborda as preocupações típicas dos desenvolvedores de que a análise estática levará seu tempo, e assim por diante.







Se você deseja compartilhar este artigo com um público que fala inglês, use o link de tradução: Maxim Zvyagintsev. Análise estática: do início à integração .



All Articles