- Confirmado um fenômeno de travamento do jogo causado por overflow de variável no motor do DOOM
- Realizado um experimento com DOOM rodando por 2,5 anos em ambiente de uso real
- À medida que o valor da variável continuava aumentando, ele chegou ao overflow e o jogo encerrou no momento previsto
- O experimento foi conduzido em um ambiente de execução automática de longo prazo usando um PDA e um UPS DIY
- Este teste comprova que um problema teórico também pode de fato ocorrer na prática
Contexto e motivação do experimento
- Há cerca de dois anos e meio, ao ler um texto sobre a estrutura e o funcionamento do motor do DOOM, foi observado que uma variável usada para rastrear a execução de demos continuava aumentando a cada início de demo
- Essa variável é comparada com o valor anterior, mas como cresce repetidamente, existe um risco inerente de overflow
- Em um ambiente de uso comum, é difícil chegar a essa situação de overflow, mas decidiu-se realizar um experimento para verificar quanto tempo isso levaria na prática
Método e processo do experimento
- Por meio de um cálculo simples, estimou-se que seriam necessários cerca de 2 anos e meio de tempo de execução até ocorrer o overflow
- Para confirmar isso de fato, foi instalado o DOOM em um PDA e a energia foi fornecida por um UPS DIY com baterias 18650
- O dispositivo foi conectado à porta USB de um roteador, mantendo continuamente a alimentação de 5 V
- Depois de configurar o sistema para funcionar continuamente em um ambiente de carregamento automático, ele foi deixado praticamente sem supervisão durante a maior parte do tempo
Ocorrência do travamento e resultados
- Cerca de dois anos e meio após o início do experimento, foi confirmado o aparecimento de uma notificação pop-up na tela do dispositivo
- O DOOM, como previsto, entrou em estado de travamento fatal causado por overflow
- O resultado do experimento comprovou que o encerramento do jogo causado por overflow de variável realmente pode acontecer em hardware real e em um ambiente real de software
Conclusão e implicações
- O experimento reforça a importância de ter cuidado, na programação, com variáveis que acumulam e aumentam ao longo de longos períodos
- Foi confirmado experimentalmente que um problema de overflow antes visto apenas como possibilidade teórica pode realmente explodir no mundo real
- Isso serve de alerta para falhas ocultas em código legado ou em softwares que operam por longos períodos
1 comentários
Comentários no Hacker News
Há cerca de um ano, enquanto eu analisava o sistema de timer de Crash Bandicoot, descobri que em Crash 3 um valor do tipo int32 continua aumentando, e a estrutura é tal que ele só é resetado quando você morre. Se o jogo ficar ligado por 2,26 anos, ocorre um overflow. Nesse momento, o tempo vira “negativo” e o jogo quebra de várias formas engraçadas. Fiz um vídeo sobre isso: link do YouTube
Em Final Fantasy 9, para obter uma arma específica, você precisa chegar a uma área do fim do jogo em até 12 horas (10 horas na versão europeia), mas por causa de um bug também dá para consegui-la deixando o jogo ligado por 2 anos até o timer estourar. Dá para esperar com calma e ainda alcançar o objetivo. Link com explicação detalhada
Acho curioso que no seu vídeo você não tenha feito nem um trocadilho com “crash”. Dava até para chamar o travamento de crash, então ficou faltando um pouco disso
Fico me perguntando se é comum usar signed integer por padrão para rastrear timers. Se fosse unsigned, o tempo até o overflow seria o dobro, então fico curioso sobre por que fizeram essa escolha
Acho que muitos jogos eram assim. SotN também tem um timer global. Em sistemas de 32 bits, para jogos que seriam usados por alguns meses, ou no máximo alguns anos, eles provavelmente não viam necessidade de testar a passagem de vários anos. Na época, ninguém imaginava que o software que fazia seria hackeado, analisado e submetido a engenharia reversa. Nós também não costumamos pensar muito nisso ao programar no dia a dia
Isso sim é desbloquear o verdadeiro Time Twister
Parece uma situação em que o jogo se torna impossível de jogar. Espero que alguém realmente conserte isso. Doom é um jogo excelente e eu sempre volto a ele a cada alguns anos. O reboot de 2016 também foi divertido, mas os títulos posteriores, pessoalmente, não me agradaram muito
Existe uma comunidade para quem prefere a jogabilidade no estilo clássico de Doom: r/boomershooters
Sinto o mesmo. O design metroidvania e a estrutura de hub central dos títulos recentes não passam a mesma sensação de antes. Gosto mais da progressão simples de correr, matar inimigos, achar segredos e passar para a próxima fase
Eu também, especialmente gosto muito do modo brutality
Curiosidade: agora Doom pertence à Microsoft, junto com Quake, StarCraft, WarCraft, Overwatch, todos os jogos de aventura da Infocom e da Sierra, e também Halo. A Microsoft tenta dominar a maior parte da propriedade intelectual dos jogos de PC desde 1996, então dá para dizer que praticamente conseguiu
O jogo de 2016 foi o melhor FPS single-player que já joguei. O único que chegou perto foi Titan Fall 2
Fico me perguntando se existe algum recurso no hardware para trapar overflow. Lendo textos sobre o funcionamento do motor de Doom, vi que a variável que rastreia demos continua aumentando mesmo quando a demo seguinte começa. Essa variável é comparada com uma segunda variável que guarda o valor anterior. Fico curioso sobre por que exatamente o jogo real acabou crashando
É preciso agradecer por já saberem de antemão qual era a causa do bug. Também poderia ter acontecido de, depois de 2,5 anos, alguém perceber: “droga, esqueci de ligar o log de debug”
O DOOM crashou antes do Windows CE
O que mais me impressiona é um aplicativo ter ficado rodando continuamente por 2,5 anos em um PDA. Tenho sérias dúvidas se algo assim seria possível hoje em hardware moderno, ainda mais desconectado da internet
É realmente um feito impressionante
Como o site parece ter caído por excesso de acessos, deixo um link do archive.org: link para a cópia no archive.org. Infelizmente, nem todo o formato da página foi preservado, mas o texto está lá
2038 parece que vai ser um ano interessante
Muita gente ignora o problema do NTP em 2036. É ali que a festa de verdade começa
2038 parece muito mais próximo do que a época do y2k
Faltam 13 anos para fazer upgrade para int de 64 bits ou trocar
time_tpara o tipolong long. Muitos dispositivos embarcados e sistemas fechados sem suporte vão precisar de atenção especial. O OpenFirmware do meu antigo SunServer 600MP também tinha esse mesmo problema. Felizmente, agora já não é mais algo com que eu precise me preocuparResolver esse problema é o meu plano de aposentadoria
Esse é o tipo de teste que nenhum tester que eu conheço faria. No sistema em que trabalho, ontem mesmo eu tive que esperar mais de cinco vezes para verificar o tratamento de erro após um timeout de 30 segundos, e já foi irritante o bastante
Houve um tempo em que o Windows NT 4 também tinha um bug parecido. Era um contador de alta precisão que media o uptime do sistema. Antes do Service Pack 3 (ou 2), a gente reiniciava o sistema com o agendador todo dia 1º de cada mês. Caso contrário, ele crashava depois de cerca de 42 dias de uptime. Nem a Microsoft achava que um sistema operacional de servidor ficaria rodando continuamente por tanto tempo
Mais uma vez, aplausos para a equipe da id Software. Se isso tivesse sido desenvolvido do jeito mais comum de hoje, provavelmente já teria morrido antes de passar de 2 anos por fragmentação de memória ou vazamentos de memória