Larry Hardesty - MIT - 15/08/2011
O programa travou
Já aconteceu com todo mundo: você está usando um programa bem conhecido para fazer algo que você já fez mil vezes antes - por exemplo, encontrar uma determinada palavra em um documento - e, de repente o programa simplesmente pára de funcionar.
Você tecla, clica, move o mouse, mas nada muda na tela, e, finalmente, você acaba tendo que sair do programa, perdendo o trabalho que fez desde a última vez que salvou o arquivo.
Muitas vezes, um programa entra naquilo que os cientistas chamam de um loop infinito, quando ele fica executando continuamente o mesmo bloco de código.
Agora, pesquisadores do MIT apresentaram uma nova ferramenta que consegue interromper automaticamente os loops infinitos e passar para a próxima linha de código do programa.
Nos testes, o sistema restaurou cinco programas diferentes para estados estáveis o suficiente para que os dados pudessem ser salvos e os programas fossem encerrados com segurança. Na maioria dos casos, os programas também ofereceram ao menos uma solução parcial para os cálculos que eles estavam tentando realizar quando travaram.
Loops e loops infinitos
Os loops estão entre os blocos mais básicos dos programas de computador. Eles permitem que um programador especifique apenas uma vez uma rotina que deve ser realizada em vários segmentos de dados em sequência.
Por exemplo, a função de pesquisa em um processador de texto pode ter que olhar para milhares de letras individuais em um documento, comparando cada uma das sequências com as letras do termo digitado na caixa de pesquisa.
Se ele não encontrar uma correspondência, vai passar para a próxima letra e reiniciar o loop para re-executar o mesmo código, que fará a comparação com a sequência a partir da próxima letra. E assim por diante.
Um programa comercial pode conter dezenas de milhares de loops, e mesmo um pequeno erro no código de qualquer um deles pode levar a um loop infinito, no qual o computador não sabe quando parar de repetir a mesma operação.
Encontrando a finitude do loop
A nova ferramenta de software, que os cientistas batizaram de Jolt - algo como "chacoalhão" -, identifica os loops infinitos monitorando o uso que o programa faz da memória.
Um usuário que esteja preocupado se seu computador entrou em um loop infinito pode ativar o Jolt, que gera uma série de "fotografias" da memória do computador após cada iteração do loop.
"Os instantâneos podem ser completamente diferentes," explica Michael Carbin, um dos desenvolvedores do Jolt. "Isso pode ser um indicador de que seu programa ainda está fazendo cálculos corretamente. Ele pode estar fazendo algo de útil para você, então você não vai querer interrompê-lo. Mas se não é, se os instantâneos são sempre repetidos, então fica claro que o programa está preso em um loop infinito."
O Jolt funciona em conjunto com um compilador, um programa que traduz o código escrito em uma linguagem de programação de alto nível em instruções que um computador consegue entender.
Quando uma aplicação está sendo compilada, o Jolt marca o início e o fim de todos os loops indicados no código fonte. Se o aplicativo, depois de compilado, travar, o Jolt simplesmente o obriga a pular para a primeira instrução após o loop em que ele está preso.
No mundo real
Manter marcações em todos os loops de um programa, contudo, faz com que ele rode 7 ou 8 por cento mais lento, diz Carbin.
E fazer os desenvolvedores de software comerciais usarem o Jolt ao compilar os seus códigos pode ser uma tarefa difícil.
Assim, os pesquisadores estão trabalhando em uma versão do Jolt que opera diretamente com aplicações compiladas, cujas instruções consistem inteiramente de sequências de números binários de comprimento fixo. Esta versão binária do Jolt, explicam os pesquisadores, será chamada Bolt.
O Bolt usa o mesmo mecanismo de detecção de loops infinitos que o Jolt e, nos primeiros testes, ele parece funcionar bem com arquivos binários. O maior desafio é determinar para qual instrução saltar depois que o loop foi identificado.
Uma função escrita em uma linguagem de programação de alto nível pode chamar outras funções, que podem chamar ainda outras funções. Mas, no nível binário, as chamadas de função aninhadas são apenas uma longa lista de números. Descobrir onde termina uma função e começa outra não é uma tarefa fácil.
Mas Michael Kling, outro desenvolvedor do projeto, criou um algoritmo inteligente que consegue identificar a função de nível mais alto em operação em um determinado momento - aquela que chamou todas as outras - o que pode ajudar o Bolt a se orientar.
E, mesmo se o sistema não conseguir tomar a decisão mais correta possível, afirma Rinard, ele pode simplesmente começar a circular por todas instruções seguintes ao acaso, até encontrar uma que rompa o impasse.
Ética na computação
Modificar aleatoriamente o código em tempo de execução pode soar antitético a toda a noção de engenharia da computação, mas é uma abordagem que valeu a pena para o grupo, ao menos em uma pesquisa em sites que contêm ataques maliciosos e softwares que se ajustam às condições variáveis de hardware, entre outras coisas.
"A grande maioria da engenharia de software, ou dos pesquisadores de linguagens de programação, está acorrentada a esta noção de correção total ou de solidez completa: Você não pode mudar nada no programa se houver a menor possibilidade de que você obtenha uma resposta ligeiramente errada," comenta Weimer Westley, professor assistente de ciência da computação na Universidade de Virginia. "Uma das coisas que realmente caracteriza a pesquisa de Martin nos últimos 10 ou 15 anos é lançar fora os grilhões da solidez em favor de abordagens que são apenas provavelmente corretas, mas dramaticamente mais úteis na vida real."
Weimer reconhece que, no caso do Bolt, determinar para qual instrução saltar é um problema difícil e, devido a alguns resultados fundamentais em ciência da computação, "Eu tenho como dado que ele nunca vai ser capaz de estar absolutamente certo. Mas ele será capaz de descobrir a grande maioria dos loops infinitos."
Pode haver alguns casos em que o Bolt vai errar, diz Weimer. "Mas a comparação - e isto é importante para este tipo de trabalho - é que, se ele não pular, você estará preso em um loop infinito. A comparação não é que ele estava funcionando bem e você mexeu com ele."