Aumentando a Confiabilidade em Programas C com VeriFast
Um olhar sobre como o VeriFast melhora a verificação de programas em C usando sistemas formais.
― 7 min ler
Índice
Nos últimos anos, garantir que os programas de computador sejam corretos e confiáveis ficou cada vez mais importante. Uma maneira de fazer isso é por meio de um processo chamado Verificação, que checa se um programa se comporta como esperado. Nesse contexto, vamos ver como uma ferramenta chamada VeriFast ajuda a verificar programas em C, especialmente em relação a um sistema formal chamado CH2O. Este artigo vai explicar os métodos usados para garantir que os programas estejam corretos, descrever as melhorias feitas no VeriFast e apresentar um exemplo simples de como a verificação funciona.
Fundo sobre Verificação
Verificação é o processo de confirmar que um programa se comporta como pretendido. Para programas em C, que são frequentemente usados para construir vários softwares, é crucial garantir que eles não tenham comportamentos indefinidos. Comportamentos indefinidos podem levar a sérios problemas, como acessar a memória que o programa não deveria, ou causar condições de corrida onde múltiplos processos tentam mudar os mesmos dados ao mesmo tempo.
O VeriFast é uma ferramenta desenvolvida para ajudar nesse processo de verificação. Ela pega programas em C e os verifica contra certas regras e especificações para ver se eles se comportam corretamente. No entanto, é importante notar que, embora o VeriFast seja uma ferramenta útil, ele mesmo não foi formalmente verificado. Isso significa que não podemos confiar totalmente em sua correção sem adicionar uma camada extra de verificação.
O Papel do Coq e CH2O
Para lidar com a incerteza em torno do VeriFast, um passo adicional foi introduzido. Usando um assistente de provas chamado Coq, podemos criar um certificado de correção para cada execução de verificação bem-sucedida de um programa C. Este certificado é essencialmente uma prova formal que mostra que o programa está correto de acordo com um conjunto de regras definidas por outro sistema conhecido como CH2O.
O CH2O fornece uma maneira formal de entender programas em C, especialmente aqueles que seguem o padrão C11. Isso significa que, quando um programa é verificado usando o CH2O, é garantido que ele funcione corretamente com qualquer compilador que também seja compatível com o C11.
Melhorias no VeriFast
Os esforços para melhorar o VeriFast focam em duas áreas principais. Primeiro, o código Coq usado para verificação foi reorganizado para usar uma ferramenta de biblioteca chamada STDPP. Essa atualização simplifica muitos aspectos do processo de prova, tornando-o mais fácil e eficiente.
Em segundo lugar, o backend principal do VeriFast foi trocado de CompCert para CH2O. Essa mudança é significativa porque o CH2O fornece uma semântica formal de C que é fiel ao padrão C11 subjacente. Os benefícios dessa atualização incluem um modelo de memória interessante que permite tanto operações de baixo nível quanto análises de compiladores de nível mais alto.
O Desafio da Complexidade
O VeriFast é uma ferramenta complexa com várias funcionalidades, tornando difícil verificar diretamente. O objetivo original de verificar o próprio VeriFast parecia uma tarefa assustadora devido às suas complexidades internas. No entanto, uma solução foi encontrada ao estender o VeriFast para produzir provas verificáveis por máquina a cada execução de verificação bem-sucedida.
Essas provas vêm na forma de scripts Coq que, quando verificados, demonstram que o programa C original está correto de acordo com as especificações definidas.
Como a Verificação Funciona
Para ilustrar como a verificação acontece, podemos olhar para um programa C simples. Este exemplo mostrará como os diferentes passos do processo de verificação se juntam.
Programa de Exemplo
Considere um programa C simples que conta regressivamente a partir de um número dado. O primeiro passo no processo de verificação envolve rodar uma ferramenta que gera um script Coq contendo a árvore de sintaxe abstrata (AST) para esse programa. A AST é uma representação estruturada do programa que ajuda no processo de verificação.
Em seguida, rodamos o VeriFast nesse programa C usando uma flag específica que diz a ele para gerar uma prova Coq. O resultado é outro script Coq que contém a prova gerada pelo VeriFast.
Finalmente, compilamos ambos os scripts Coq para checar se a prova está correta. Se o compilador Coq aceitar a prova, podemos concluir que o programa atende às condições especificadas.
Analisando os Scripts Coq
O script Coq gerado pela ferramenta CH2O contém todas as declarações necessárias do programa, enquanto o script gerado pelo VeriFast inclui as anotações e condições que guiam a verificação. O próximo passo envolve traduzir a AST C abstrata do CH2O para outra forma adequada para a prova.
Estabelecer a relação entre essas duas formas é vital para a validade da prova. Uma vez que essa relação seja estabelecida, podemos demonstrar a correção ligando-a à execução do programa original, garantindo que o programa se comporte como esperado.
A Importância da Solidez
Solidez neste contexto significa que, se um programa é provado correto pela ferramenta de verificação, ele deve se comportar corretamente quando executado. Isso é crucial porque fornece uma camada de confiança na confiabilidade do programa.
Ao relacionar a correção do programa a princípios de correção conhecidos dentro do CH2O, podemos criar uma cadeia de raciocínio que apoia nossas afirmações de correção.
Essa cadeia inclui várias transformações e etapas que, em última análise, mostram que o programa atende às suas especificações sem encontrar comportamentos indefinidos.
Desafios à Frente
Embora os processos mencionados acima sejam eficazes, ainda existem desafios a serem resolvidos. O conjunto atual de funcionalidades nos programas C suportados é limitado. Trabalhos futuros requererão a adição de mais recursos, como ponteiros, estruturas e alocação dinâmica de memória.
Além disso, a capacidade de verificar programas mais complexos significa que as ferramentas de verificação atuais podem precisar ser aprimoradas ou adaptadas. À medida que os programas se tornam mais complicados, novas estratégias serão necessárias para lidar com tarefas de verificação cada vez mais complexas.
O suporte para programas concorrentes é outro desafio significativo. Como tanto o CH2O quanto o CompCert são de thread única, lidar com múltiplas threads exigirá um planejamento cuidadoso e semântica adicional.
Conclusão
Em conclusão, verificar programas C é essencial para criar softwares confiáveis e livres de bugs. A ferramenta VeriFast, combinada com os sistemas formais do CH2O e Coq, oferece uma maneira promissora de realizar essa tarefa. As melhorias contínuas nessas ferramentas e técnicas visam reforçar o processo de verificação, garantindo que programas C mais complexos possam ser efetivamente validados em relação aos comportamentos esperados.
À medida que avançamos, a integração de mais recursos e o desenvolvimento de estratégias para lidar com cenários complexos aumentarão ainda mais a capacidade de confiar na correção do software. Esse esforço contínuo, em última análise, contribuirá para o campo da confiabilidade de software, garantindo que os programas funcionem corretamente e de forma segura em diversos ambientes.
Título: Certifying C program correctness with respect to CH2O with VeriFast
Resumo: VeriFast is a powerful tool for verification of various correctness properties of C programs using symbolic execution. However, VeriFast itself has not been verified. We present a proof-of-concept extension which generates a correctness certificate for each successful verification run individually. This certificate takes the form of a Coq script which, when successfully checked by Coq, removes the need for trusting in the correctness of VeriFast itself. The Coq script achieves this by applying a chain of soundness results, allowing us to prove correctness of the program with regards to the third-party CH2O small step semantics for C11 by proving correctness in terms of symbolic execution in Coq. This proof chain includes two intermediate auxiliary big step semantics, the most important of which describes VeriFast's interpretation of C. Finally, symbolic execution in Coq is implemented by transforming the exported AST of the program into a Coq proposition representing the symbolic execution performed by VeriFast itself.
Autores: Stefan Wils, Bart Jacobs
Última atualização: 2023-08-29 00:00:00
Idioma: English
Fonte URL: https://arxiv.org/abs/2308.15567
Fonte PDF: https://arxiv.org/pdf/2308.15567
Licença: https://creativecommons.org/licenses/by/4.0/
Alterações: Este resumo foi elaborado com a assistência da AI e pode conter imprecisões. Para obter informações exactas, consulte os documentos originais ligados aqui.
Obrigado ao arxiv pela utilização da sua interoperabilidade de acesso aberto.