Técnica do C-Reduce que pode ser usada em qualquer linguagem
(bernsteinbear.com)- C-Reduce é uma ferramenta para reduzir código de reprodução de bugs em compiladores C, mas também pode ser aplicada a outras linguagens se houver uma condição determinística, uma reprodução rápida e arquivos-fonte modificáveis
- O exemplo mostra o processo de reduzir um bug ocorrido ao executar scrapscript no RustPython, em que
interesting.shdetermina se a reprodução ocorre procurando uma mensagem de erro específica - Apenas executando
creduce --not-c interesting.sh scrapscript.py, o tamanho do arquivo diminuiu rapidamente, com progresso mostrando uma redução de quase 50% logo no início --not-cé uma opção que evita passes de redução específicos de C, ajudando a reduzir tempo de execução desnecessário em entradas como Python- Se for possível criar um script curto com a condição que reproduz o bug, relatórios de bug de linguagens que não são C também podem ser tornados menores e mais fáceis de lidar com C-Reduce
Condições para usar C-Reduce em entradas que não sejam C
- C-Reduce é uma ferramenta criada por Regehr e colegas para minimizar código de reprodução de bugs em compiladores C
- Quando um arquivo C de 10.000 linhas causa um bug no Clang, ela pode ser usada para reduzi-lo automaticamente em vez de enviar o arquivo enorme como está
- Embora pareça uma ferramenta exclusiva para C, ela também pode ser usada com entradas de outras linguagens se as seguintes condições existirem
-
Condição determinística
- Um método de reprodução relativamente rápido que ajude na velocidade da redução
- Um ou mais arquivos-fonte modificáveis que o C-Reduce possa reduzir
- A condição determinística também pode ser simulada probabilisticamente usando um wrapper em loop
-
Exemplo de redução de reprodução de bug no RustPython
- Um bug ocorreu ao executar scrapscript no RustPython, e foi escrito um script
interesting.shpara reportá-lo - O script executa
scrapscript.pyusando o caminho absoluto do binário do RustPython e então procura a seguinte string na saída, incluindo o erro padrãotried to push value onto stack but overflowed max_stackdepth
- O comando de execução é o seguinte
creduce --not-c interesting.sh scrapscript.py
- O C-Reduce executa testes de interestingness em paralelo e reduz rapidamente o tamanho do arquivo
- O progresso do exemplo é exibido como 0,5%, 9,2%, 18,1%, 47,5% etc.
- Em poucos segundos, o arquivo foi reduzido em quase 50%
- No momento em que o texto foi concluído, chegou a 96,9% de redução
- Sem usar
--not-c, o C-Reduce usa muitos passes específicos para C- Em entradas Python, esses passes podem tornar a execução mais lenta
- É provável que isso não altere substancialmente o resultado em si
- O conteúdo relacionado foi posteriormente movido para a página Delta debugging
1 comentários
Opiniões no Hacker News
Como não compartilharam o arquivo reduzido, rodei por conta própria. Compilei o
RustPython, peguei oscrapscript.py, alterei o caminho eminteresting.she executei comnix run nixpkgs#creduce -- --not-c interesting.sh scrapscript.py; no fim, ele parou por volta de 96,4%, 7347 bytes, e o resultado está em https://gist.github.com/judofyr/47cba8a20cb2cd5798943ef975d0...shrinkray, rodando por uns 10 minutos, reduz até 162 bytes: https://gist.github.com/DRMacIver/ee025c90b4867125b382a13aaa...Se deixar mais tempo, talvez melhore um pouco, mas parecia quase travado, então fiquei entediado e encerrei
John Regehr, autor do C-Reduce, também recomenda experimentar o
Shrinkraypara esse uso. Ele diz que oShrinkrayfoi feito para funcionar independentemente do formato e que é uma boa ferramenta mesmo nos casos em que o C-Reduce não se sai bem: https://mastodon.social/@regehr/113489759789563570Shrinkray? https://github.com/DRMacIver/shrinkraycvise: https://github.com/marxin/cviseÉ uma alternativa em Python que funciona razoavelmente bem também com linguagens que não são C
Há um artigo de 2012, de John Regehr e outros autores, que explica como ele funciona: https://fsl.cs.illinois.edu/publications/regehr-chen-cuoq-ei...
Pelo que me lembro, a maior parte das reduções não específicas de domínio do C-Reduce é algo próximo de força bruta simples
Acabei de conhecer o C-Reduce e já fiquei fascinado. É parecido com quando descobri o git bisect pela primeira vez
Preciso guardar isso em algum canto da cabeça para usar quando um dia aparecer a situação certa
Estou pensando em configurar isso. Como o VICE oferece suporte a “emitir saída” para um arquivo do sistema operacional host, parece que daria para rodar os testes no emulador
Delta debugging não é um conceito novo: https://en.wikipedia.org/wiki/Delta_debugging
Minha implementação de delta debugging,
delta, tem mais de 19 anos: https://github.com/dsw/deltaNa época em que a Microsoft chamava open source de “câncer”, a Microsoft Research mandou gente até meu escritório pedindo que eu a tornasse pública, então lancei como open source. A introdução de Latner ao LLVM também menciona a “ferramenta padrão de delta debugging”, então é uma ferramenta bastante conhecida: https://aosabook.org/en/v1/llvm.html
Ou seja, a conclusão é que uma redução eficaz de programas exige mais do que delta debugging simples. Claro que o C-Reduce também já é uma ferramenta de 12 anos
Ao mesmo tempo, a ferramenta do LLVM linkada,
BugPoint, é específica para LLVM IR, enquanto o C-Reduce parece mais geral. Ferramentas e técnicas de minimização automática de casos de teste ainda são desconhecidas para a maioria dos desenvolvedores; portanto, mesmo sendo uma ideia conhecida há muito tempo nessa área, este texto pode ser útilEncontrei um texto com exemplos de antes e depois: https://pramodkumbhar.com/2024/01/c-reduce-systematically-ta...
Ainda assim, não entendo bem como ele sabe o que remover em cada iteração. Deve haver algum nível de tokenização, mas não sei como isso funciona entre várias linguagens de programação
creduceé excelenteQuando eu desenvolvia um backend de target esotérico para LLVM, escrevi um script de teste que gerava programas de teste aleatórios por horas com o
CSmith. Quando havia um crash, ele rodava automaticamente o C-Reduce e deixava um arquivo para eu inspecionar, o que ajudava muitoTambém funciona bem com SQL. Uso no trabalho e conheci por meio de https://github.com/sqlancer/sqlancer?tab=readme-ov-file#redu...
É uma afirmação difícil de acreditar se não explicarem por que funciona também em linguagens além de C. Não acho que seja mentira, mas dizer que faz isso sem LLM é surpreendente
Por exemplo, a estratégia de tokenizar a entrada no estilo C e depois descartar aleatoriamente blocos de tamanho por volta de 1 a 13 funciona bem para remover qualificadores ou atributos desnecessários, porque a maioria das linguagens parecidas com C tem regras de tokenização semelhantes. Um passe que remove unidades de parênteses balanceados
(),{},[]também é útil em praticamente qualquer linguagem. Remover comentários e espaços em branco também é eficaz porque muitas linguagens usam os estilos/* */e//, como CNa prática, não há muitos passes que sejam realmente específicos de C/C++. Pela minha experiência, uma das grandes fraquezas do
creduceé que ele é muito ruim na etapa de redução que remove templates, ou seja, uma tarefa que parece relativamente fácil de automatizarAlgumas transformações são bem específicas de C, usando o frontend do Clang, e outras são bastante gerais, então provavelmente funcionam em geral com linguagens da família Algol. Como é uma ferramenta modular, se quiser você pode adicionar transformações que entendam outras linguagens
O que estou falando aqui são coisas como algoritmos, não aquele aprendizado de máquina assustador. Isso inclui coisas como usar Prolog para IA, embora tenha o pequeno ponto negativo de não funcionar muito bem para o objetivo de criar IA
creducepoderia executar o script de entrada modificado e apagar meus arquivos ou comer meu almoço?Como ele se compara ao
dustmite? https://dlang.org/blog/2020/04/13/dustmite-the-general-purpo...