"Meu bug mais difícil de todos", um desafio no desenvolvimento do Crash Bandicoot 1
Em 2013, Dave Baggett compartilhou uma história de seu "bug mais difícil de todos". Isso aconteceu no desenvolvimento do Crash Bandicoot 1, e vou trazer a história resumida para cá.
O bug, a depuração e a descoberta
Achei que levaria alguns dias. Acabei depurando esse código por 6 semanas. Fiz outras coisas durante esse tempo, mas continuei voltando a esse bug - algumas horas a cada poucos dias. Foi agonizante.
O sintoma do bug acontecia ao salvar o progresso no jogo. Ao salvar, ele acessava o cartão de memória, e quase sempre funcionava normalmente, mas de vez em quando a gravação ou leitura expirava (timeout) e uma gravação curta geralmente corrompia o cartão de memória. Ou seja, além de não salvar o progresso, todos os dados do cartão de memória eram perdidos.
Via Connie [o produtor deles na Sony], divulgamos a outros desenvolvedores do PS1 - alguém já viu algo assim? Não. Absolutamente ninguém teve problemas com o sistema de cartão de memória.
Para depurar, o Dave foi removendo partes do código e substituindo pelo código mais simples possível de forma que o jogo pudesse continuar funcionando e este código não ser o culpado pelo bug.
Continuei removendo mais e mais pedaços de código até que acabei, praticamente, com nada além do código de inicialização - apenas o código que configurou o sistema para executar o jogo, inicializou o hardware de renderização etc. Não coloquei o menu carregar/salvar nesse ponto porque eliminei todo o código gráfico. Mas eu poderia fingir que o usuário usou a tela de carregamento/salvar (invisível) e pediu para salvar e depois gravar no cartão.
Mesmo assim, o problema continuava — e pior, de forma aleatória.
E se algo em nosso código de configuração estivesse atrapalhando o tempo de alguma forma? Olhei novamente para o código no programa de teste para coisas relacionadas ao tempo e notei que definimos o temporizador programável no PS1 para 1kHz (1000 tiques/segundo). Isso é relativamente rápido; ele estava rodando em algo como 100 Hz em seu estado padrão quando o PS1 foi inicializado. A maioria dos jogos, portanto, teria esse cronômetro rodando a 100 Hz.
Nesse ponto, o Andy, o principal (e único outro) desenvolvedor do jogo, definiu o cronômetro para 1kHz para que os cálculos de movimento no Crash fossem mais precisos. Parecia que o problema não acontecia mais.
Com o passar dos dias, continuei brincando com meu programa de teste. O bug nunca mais aconteceu. Voltei à base de código completa do Crash e modifiquei o código de carregamento/salvamento para redefinir o cronômetro programável para sua configuração padrão (100 Hz) antes de acessar o cartão de memória e, em seguida, colocá-lo de volta em 1 kHz. Nunca mais vimos os problemas de leitura/gravação.
O Dave continuou tentando entender o problema. Qual era o padrão para isso acontecer? Eventualmente, percebeu que o problema acontecia quando alguém estava usando o controle do PS1.
Depois que percebi que as duas coisas estavam correlacionadas, foi fácil reproduzir: começar a gravar no cartão de memória, mexer no controle, corromper o cartão de memória. Claro que parecia um bug de hardware para mim.
De fato, era um problema de hardware. Ele avisou o Connie, que confirmou e avisou a Sony. A conclusão de Dave de acordo com o retorno que teve da Sony foi essa:
Nunca fui totalmente claro sobre qual era o problema exato, mas minha impressão pelo que ouvi da Sony HQ foi que definir o timer programável para uma taxa de clock suficientemente alta interferiria nas coisas na placa-mãe perto do cristal do timer. Uma dessas coisas era o controlador de taxa de transmissão para o cartão de memória, que também definia a taxa de transmissão para os controladores. Eu não sou um cara de hardware, então estou muito confuso sobre os detalhes.
Mas a essência disso era que a diafonia entre partes individuais na placa-mãe e a combinação de envio de dados pela porta do controlador e pela porta do cartão de memória enquanto executava o cronômetro a 1kHz faria com que os bits fossem descartados... e os dados perdidos... e o cartão corrompido.
Esta é a única vez em toda a minha vida de programação que depurei um problema causado pela mecânica quântica.