NewsTecnologia
Tendência

Bug do Word 97 “sumia” quando engenheiros tentavam investigá-lo; causa estava no processador

Falha descoberta na reta final do desenvolvimento do Microsoft Word 97 conseguia derrubar o programa durante os testes, mas desaparecia assim que os engenheiros ativavam o debugger. A investigação acabou revelando um defeito específico de CPU e levou a Microsoft a corrigir diretamente o arquivo binário do Word com uma única instrução.

Um episódio dos bastidores do desenvolvimento do Microsoft Word 97 mostra como alguns dos problemas mais difíceis da computação podem surgir justamente da interação entre software e hardware.

Na reta final do desenvolvimento do programa, engenheiros da Microsoft encontraram um bug considerado grave o suficiente para impedir o lançamento. O Word apresentava travamentos aparentemente aleatórios durante os testes.

Havia, entretanto, algo ainda mais estranho: a equipe possuía um script capaz de reproduzir o crash com uma frequência razoável, mas, sempre que os desenvolvedores tentavam acompanhar o problema utilizando um debugger, a falha simplesmente desaparecia.

A história foi relembrada em agosto de 2026 por Raymond Chen, veterano da Microsoft e autor do blog técnico The Old New Thing. Chen trabalha há mais de três décadas acompanhando a evolução do Windows.

O caso é especialmente interessante porque a origem não estava propriamente no código-fonte do Word.

O culpado era um comportamento defeituoso de determinados processadores.

Bug apareceu no pior momento possível

O Word 97 estava praticamente pronto.

Nessa fase de desenvolvimento, conhecida informalmente como end game, qualquer alteração significativa representa um risco.

Um programa do tamanho do Word possui milhões de combinações possíveis de operações. Mudar um componente importante poucos dias ou semanas antes do lançamento pode resolver um problema e introduzir vários outros.

Foi justamente nesse estágio que a equipe encontrou o crash.

Segundo Chen, tratava-se de um erro em um caminho de código relativamente comum, tornando o problema especialmente preocupante.

Nos computadores de teste, o comportamento aparecia apenas ocasionalmente.

Isso não tranquilizou os desenvolvedores.

Na realidade, aconteceu o contrário.

Um bug raro no laboratório poderia virar um problema enorme

Existe uma questão de escala importante no desenvolvimento de software.

Uma falha que acontece uma vez a cada milhares de operações pode parecer pequena quando um programa é testado por algumas dezenas ou centenas de computadores.

Mas o Word seria instalado em milhões de máquinas.

Nesse cenário, um evento extremamente raro passa a acontecer diariamente para algum usuário.

Raymond Chen resume justamente essa preocupação: um bug que aparece esporadicamente no laboratório pode ocorrer regularmente quando o produto chega ao mundo real.

Por isso, simplesmente ignorar o problema não era uma alternativa.

A equipe precisava descobrir sua origem antes do lançamento.

O problema desaparecia quando o debugger era usado

Normalmente, quando um programa trava, os desenvolvedores tentam reproduzir a situação utilizando ferramentas de depuração.

O debugger permite acompanhar a execução do software, examinar memória, observar variáveis e interromper o programa em determinados pontos.

Era exatamente isso que os engenheiros tentaram fazer.

Só que havia um problema.

Ao executar o Word sob o debugger, o crash deixava de acontecer.

Esse tipo de comportamento está entre os mais frustrantes para engenheiros de software.

A ferramenta utilizada para observar o problema altera as condições necessárias para que o próprio problema aconteça.

Na computação, bugs dessa natureza são frequentemente associados ao conceito de Heisenbug.

O nome faz referência ao princípio da incerteza de Heisenberg, da física: metaforicamente, observar o sistema modifica seu comportamento.

Microsoft cogitou usar um equipamento incomum

Sem conseguir capturar a falha utilizando métodos convencionais, os engenheiros começaram a considerar soluções muito mais sofisticadas.

Uma delas era utilizar um In-Circuit Emulator, ou ICE.

Esse equipamento poderia substituir fisicamente o processador da máquina por um sistema capaz de emular o comportamento da CPU.

O ICE era conectado ao soquete do processador e reproduzia os sinais elétricos que normalmente seriam gerados pela CPU.

Isso permitiria aos engenheiros observar o comportamento do computador de fora do próprio sistema.

Era possível, por exemplo, definir pontos de interrupção diretamente relacionados ao funcionamento da CPU e examinar a memória sem utilizar o debugger convencional que aparentemente fazia o bug desaparecer.

Para desenvolvedores de software, esse tipo de equipamento era bastante incomum.

Chen descreve que a possibilidade de utilizar um ICE gerou entusiasmo entre os engenheiros envolvidos na investigação.

Mas uma pista começou a mudar o rumo do caso.

Computadores que travavam tinham algo em comum

Ao analisar as máquinas afetadas, os engenheiros perceberam um padrão.

A maioria dos computadores que apresentava o crash havia sido produzida pelo mesmo fabricante.

Além disso, as máquinas problemáticas haviam sido fabricadas antes de uma determinada data.

Essa informação foi crucial.

Se o problema estivesse exclusivamente no Word, seria razoável esperar que computadores diferentes apresentassem comportamento semelhante.

Mas a concentração em determinado grupo de máquinas sugeria uma variável relacionada ao hardware.

Os investigadores passaram então a procurar problemas conhecidos nos processadores utilizados nesses computadores.

Foi quando encontraram a resposta.

Processador possuía um “erratum”

O crash estava relacionado a um CPU erratum.

Um erratum é, essencialmente, um comportamento incorreto conhecido de determinado processador.

CPUs são extremamente complexas.

Um processador moderno — e mesmo os processadores dos anos 1990 — executa enormes quantidades de operações seguindo regras muito específicas.

Em determinadas circunstâncias raras, uma combinação particular de instruções pode provocar um comportamento diferente daquele previsto pela arquitetura.

Fabricantes documentam esses problemas e frequentemente fornecem recomendações para que desenvolvedores e fabricantes de software evitem as sequências capazes de acioná-los.

Foi exatamente o que aconteceu com o Word 97.

Uma sequência específica de instruções acionava o defeito

A equipe descobriu que uma determinada sequência de código poderia disparar o problema do processador.

Mas havia mais uma condição.

Não bastava simplesmente aquela sequência existir no programa.

Para o bug ocorrer, as instruções precisavam atravessar uma fronteira de página de memória, uma condição muito específica.

Essa combinação explicava por que o problema era tão raro.

Também ajudava a explicar por que pequenas mudanças no ambiente de execução poderiam fazê-lo desaparecer.

Um debugger pode alterar layout de memória, temporização ou outros aspectos da execução.

Se isso modificasse a posição do código suficientemente para que a sequência deixasse de cruzar aquela fronteira, o defeito da CPU não seria acionado.

O resultado era o comportamento aparentemente impossível:

o Word travava normalmente, mas funcionava quando alguém tentava observar exatamente por que estava travando.

Compilador já tinha uma solução

A história poderia ter terminado de maneira relativamente simples.

O fabricante do compilador utilizado pela Microsoft já havia disponibilizado uma atualização.

A nova versão evitava gerar a sequência de instruções capaz de disparar o defeito da CPU.

Em teoria, bastaria atualizar o compilador e gerar novamente o Word.

Na prática, isso criaria outro problema potencialmente ainda maior.

O conjunto de ferramentas utilizado para construir a versão final do Word já havia sido congelado.

Atualizar o compilador poderia criar novos bugs

Trocar de compilador no final de um projeto gigantesco é uma decisão perigosa.

Mesmo que o código-fonte permaneça exatamente igual, versões diferentes de compiladores podem produzir códigos de máquina diferentes.

Podem mudar otimizações.

Podem alterar a organização das variáveis na memória.

Podem gerar sequências diferentes de instruções.

E essas alterações podem revelar bugs que anteriormente permaneciam escondidos.

Raymond Chen dá justamente um exemplo desse risco: uma variável não inicializada poderia aparentemente funcionar com o layout de memória produzido pelo compilador antigo e começar a apresentar problemas depois que o novo compilador reorganizasse aquela memória.

A Microsoft estava perto demais do lançamento para correr esse risco.

Então os engenheiros escolheram outro caminho.

Microsoft criou uma ferramenta para procurar o padrão dentro do Word

Em vez de recompilar todo o produto, a equipe decidiu descobrir exatamente onde a sequência problemática aparecia.

Os engenheiros criaram uma ferramenta para vasculhar os arquivos binários do Word procurando qualquer ocorrência da combinação de instruções associada ao defeito da CPU.

O resultado inicialmente parecia preocupante.

Foram encontradas aproximadamente 150 ocorrências da sequência problemática.

Mas havia aquela condição adicional.

Para realmente acionar o erro do processador, a sequência precisava atravessar uma fronteira de página.

Quando os engenheiros verificaram isso, descobriram algo extraordinário.

Das aproximadamente 150 ocorrências, apenas uma estava posicionada exatamente da maneira necessária para disparar o bug.

E os testes haviam conseguido encontrá-la.

Uma única instrução resolveu o problema

Agora a Microsoft sabia exatamente onde estava o problema.

Mas ainda restava decidir como corrigi-lo sem recompilar o Word inteiro.

A solução escolhida foi extremamente cirúrgica.

Os engenheiros modificaram diretamente o arquivo binário e inseriram uma instrução:

NOP.

NOP significa No Operation.

Como o próprio nome indica, é uma instrução que essencialmente manda o processador não realizar uma operação relevante naquele ciclo.

Ao inserir esse NOP no ponto específico, a Microsoft alterou a sequência de instruções o suficiente para impedir que o defeito do processador fosse acionado.

O comportamento funcional do programa permanecia praticamente igual.

Mas a sequência perigosa havia sido quebrada.

Em vez de alterar milhões de linhas, alteraram bytes

A elegância da solução estava justamente em sua precisão.

Atualizar o compilador poderia modificar enormes quantidades de código de máquina em todo o Word.

Cada alteração representaria uma nova variável que precisaria ser testada.

O patch binário, por outro lado, modificava apenas o local necessário.

O risco de regressão era muito menor.

Em desenvolvimento de software, uma regressão acontece quando uma alteração destinada a corrigir algo acaba quebrando uma funcionalidade que anteriormente funcionava.

No estágio final de um produto, minimizar esse risco é fundamental.

Por isso, a solução aparentemente improvisada era, naquele contexto, provavelmente a opção mais conservadora.

O debugger provavelmente alterava justamente a condição do bug

A história também ajuda a entender por que o erro desaparecia durante a investigação.

O defeito exigia uma combinação extraordinariamente específica:

uma determinada sequência de instruções, executada em determinados processadores e posicionada atravessando uma fronteira de página.

Alterar o ambiente de execução poderia ser suficiente para desfazer essa combinação.

É uma demonstração clássica de como bugs podem depender não apenas do código escrito pelo desenvolvedor, mas de uma cadeia inteira:

código-fonte → compilador → código de máquina → memória → processador → hardware.

Um problema em qualquer camada pode aparecer para o usuário simplesmente como: “o Word fechou sozinho”.

Word 97 chegou normalmente ao mercado

Para os consumidores, nada disso era visível.

O Microsoft Word 97 chegou ao mercado como parte do Office 97 e ficou conhecido por diversas novidades.

Uma das mais famosas foi o Clippy, o assistente animado em formato de clipe de papel.

A versão também ampliou o uso do Visual Basic for Applications (VBA), tecnologia que teria enorme importância na automação de documentos do Office.

Nos bastidores, porém, uma pequena alteração feita diretamente no binário ajudou a impedir que determinadas máquinas enfrentassem um crash extremamente difícil de diagnosticar.

Caso mostra como software e hardware são inseparáveis

É fácil imaginar um aplicativo como algo independente do computador em que está rodando.

Mas software sempre depende do comportamento correto das camadas inferiores.

O código escrito por um programador precisa ser transformado pelo compilador.

O código gerado precisa ser carregado na memória.

O processador precisa interpretar corretamente cada instrução.

Uma falha extremamente específica em qualquer uma dessas etapas pode produzir consequências inesperadas.

O caso do Word 97 é especialmente interessante porque o programa aparentemente estava fazendo algo válido.

Era o hardware que apresentava um comportamento incorreto diante de determinada sequência.

A solução, entretanto, precisou acontecer no software.

Bugs que desaparecem quando observados ainda existem

Quase três décadas depois, esse tipo de problema não desapareceu.

Sistemas modernos são muito mais complexos.

Hoje um aplicativo pode depender simultaneamente de processadores multicore, GPUs, drivers, máquinas virtuais, bibliotecas, sistemas operacionais, redes e serviços em nuvem.

Problemas relacionados a concorrência e temporização podem aparecer apenas uma vez em milhares ou milhões de execuções.

Adicionar um simples registro de diagnóstico pode alterar o tempo de execução e fazer o bug desaparecer.

É por isso que erros difíceis de reproduzir continuam entre os maiores desafios da engenharia de software.

A solução também explica uma regra importante da engenharia

O relato de Raymond Chen possui outra mensagem.

Na fase final de um produto, a melhor correção nem sempre é a mais elegante do ponto de vista teórico.

Recompilar o Word utilizando uma versão corrigida do compilador poderia parecer tecnicamente mais correto.

Mas também significaria alterar um enorme conjunto de componentes que já havia sido testado.

O patch binário era menos sofisticado, porém muito mais controlável.

Em sistemas críticos, minimizar o número de mudanças pode ser mais importante do que produzir a arquitetura mais bonita.

Cerca de 150 sequências — apenas uma era fatal

Talvez o detalhe mais impressionante da história seja justamente a improbabilidade matemática do problema.

A ferramenta da Microsoft encontrou cerca de 150 sequências potencialmente perigosas dentro dos binários.

Apenas uma delas atravessava a fronteira de página necessária para ativar o defeito da CPU.

E aquela única ocorrência era suficiente para derrubar o Word em determinadas máquinas.

Isso também mostra o valor de equipes de testes.

O problema poderia facilmente ter passado despercebido.

Em vez disso, os testadores conseguiram desenvolver um script que reproduzia a falha com frequência suficiente para impedir que ela fosse ignorada.

Um bug que parecia sobrenatural tinha explicação técnica

Durante algum tempo, o comportamento parecia quase paradoxal.

O programa travava.

Os engenheiros tentavam observar o travamento.

O programa parava de travar.

Mas não havia nada sobrenatural.

Existia uma sequência extremamente específica de código de máquina que interagia com um defeito de determinados processadores. O ambiente de depuração alterava as condições necessárias para que essa interação acontecesse.

Depois que a equipe identificou o padrão de hardware, encontrou o erratum da CPU e localizou a única sequência realmente perigosa dentro do Word, uma correção minúscula resolveu o problema.

É uma história de quase 30 anos atrás, mas continua atual porque resume um dos maiores desafios da engenharia de software:

às vezes, encontrar um bug é muito mais difícil do que corrigi-lo.

No caso do Word 97, foram necessários testes persistentes, investigação de hardware e análise dos próprios binários para chegar à causa.

No final, depois de toda essa investigação, uma única instrução NOP foi suficiente para fazer o misterioso bug desaparecer — desta vez, definitivamente.

Artigos relacionados

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Botão Voltar ao topo