- Foi descoberto no código do Apollo Guidance Computer (AGC) um bug de liberação de recurso ausente que, por 57 anos, foi considerado quase perfeito
- A equipe da JUXT analisou 130 mil linhas de assembly usando a linguagem de especificação de IA Allium e o Claude, identificando uma falha que não aparecia nos métodos tradicionais de verificação
- No caminho de término anormal (BADEND) da rotina de controle do giroscópio, o bloqueio
LGYROnão é liberado, o que pode fazer com que todas as funções relacionadas ao giroscópio parem em seguida - Se, durante a missão real, o interruptor Cage tivesse sido acionado por engano em órbita lunar, a operação de alinhamento do Program 52 poderia ter sido interrompida, e Collins poderia interpretar isso como uma falha de hardware
- Este caso mostra que a análise baseada em especificação comportamental é um método poderoso para encontrar novas falhas mesmo em códigos antigos
Defeito potencial encontrado no computador de guiagem da Apollo 11
- O Apollo Guidance Computer (AGC) é uma das bases de código mais minuciosamente revisadas da história, já analisada por inúmeros desenvolvedores e pesquisadores
- Ainda assim, foi confirmado um bug de bloqueio de recurso não liberado no código de controle do giroscópio, que permaneceu oculto por 57 anos
- O problema faz com que, em um caminho de erro, o bloqueio não seja liberado e a função de realinhamento da plataforma de guiagem seja desativada
- A equipe da JUXT usou a linguagem de especificação baseada em IA Allium e o Claude para converter 130 mil linhas de assembly do AGC em 12,5 mil linhas de especificação comportamental
- As especificações foram extraídas diretamente do código para modelar todos os caminhos de aquisição e liberação de recursos
- Nesse processo, veio à tona uma falha que não aparecia com leitura de código ou emulação tradicionais
Estrutura do código e abordagem de análise
- O código-fonte do AGC foi publicado em 2003, quando Ron Burkey e voluntários transcreveram manualmente as cópias impressas do MIT Instrumentation Laboratory
- Em 2016, o repositório de Chris Garry no GitHub foi publicado, permitindo que desenvolvedores do mundo todo examinassem o código assembly de uma máquina com 2 KB de RAM e CPU de 1 MHz
- O programa era armazenado em 74 KB de core rope memory, onde fios de cobre eram entrelaçados manualmente em núcleos magnéticos para representar 1s e 0s
- As técnicas que faziam esse trabalho eram chamadas de “Little Old Ladies”, e a memória ficou conhecida como LOL memory
- Até hoje, não havia registro de verificação formal, model checking ou análise estática aplicados ao AGC
- A maior parte da verificação se concentrou em leitura de código, emulação e conferência da precisão da transcrição
- A JUXT escreveu em Allium a especificação comportamental do subsistema IMU (Inertial Measurement Unit)
- Ao modelar os momentos de aquisição e liberação de cada recurso compartilhado, conseguiu identificar o defeito
Falta de liberação do bloqueio na rotina de controle do giroscópio
- O AGC gerencia a IMU com um bloqueio compartilhado chamado
LGYRO- Ao aplicar torque nos giroscópios, o sistema adquire o bloqueio e o libera depois que os três eixos são concluídos
- Isso impede que duas rotinas manipulem o hardware ao mesmo tempo
- Porém, no caminho de término anormal, o bloqueio não é liberado
- No encerramento normal, a rotina
STRTGYR2liberaLGYRO, mas, se ocorrer “Caging” (travamento físico de proteção do giroscópio), o fluxo vai para a rotinaBADEND - Em
BADEND, faltam as duas instruçõesCAF ZEROeTS LGYRO(4 bytes no total), e o bloqueio permanece ativo
- No encerramento normal, a rotina
- Se
LGYROnão for liberado, todas as rotinas posteriores de torque do giroscópio ficam presas aguardando o bloqueio- Alinhamento fino, correção de deriva e torque manual: todas as funções relacionadas ao giroscópio são interrompidas
Impacto potencial no lado oculto da Lua
- Em 21 de julho de 1969, Michael Collins executava periodicamente em órbita lunar o Program 52 (programa de alinhamento por observação estelar)
- Se a plataforma sofresse deriva, haveria risco de direcionamento incorreto do motor de retorno
- Se, durante uma operação de torque, o interruptor Cage tivesse sido pressionado por engano e o fluxo caísse no caminho
BADEND,LGYROpoderia não ser liberado e todos os P52 seguintes poderiam travar- O DSKY (display e teclado) aceitaria entrada, mas não responderia
- Como as outras funções continuariam normais, Collins poderia interpretar o problema como uma falha de hardware
- Um reinício (hard reset) teria resolvido o problema, mas, por causa da experiência com o alarme 1202 durante o pouso lunar, decidir por um reset imediato provavelmente não teria sido simples
Projeto defensivo do sistema existente e seus limites
- A equipe do MIT liderada por Margaret Hamilton introduziu conceitos fundamentais da engenharia de software moderna, como escalonamento por prioridade, multitarefa assíncrona e proteção contra reinicialização
- Graças a esse projeto, o pouso foi possível mesmo durante o alarme 1202
- A maioria dos defeitos importantes estava ligada a erros de especificação; como documentado por Don Eyles, houve casos em que a ausência de sincronização de fase entre hardwares aumentou a carga da CPU
- Este defeito atual tem estrutura semelhante
BADENDé uma rotina geral de término para transições de modo da IMU e libera recursos comuns comoMODECADR, mas não trataLGYRO- Como a lógica de reinicialização inicializa
LGYRO, o problema se recuperava sem dificuldade nos testes e acabou ficando oculto
- Porém, em uma situação real sem reinicialização, o giroscópio poderia permanecer travado permanentemente
Como a falha foi descoberta com Allium
- A especificação em Allium modela o ciclo de vida (lifecycle) de cada recurso
- O campo
gyros_busyrepresentaLGYRO, a regraGyroTorquedefine a aquisição do bloqueio e a regraGyroTorqueBusydefine o estado de espera quando ele já está ocupado
- O campo
- A especificação declara a obrigação de que “se o bloqueio virar true, ele deve obrigatoriamente voltar para false”
- Depois que o Claude rastreou todos os caminhos, ficou claro que a liberação acontece no caminho normal (
STRTGYR2), mas falta no caminho de erro (BADEND)
- Depois que o Claude rastreou todos os caminhos, ficou claro que a liberação acontece no caminho normal (
- A abordagem baseada em especificação verifica não o que o código faz, mas o que ele deveria fazer
- Testes confirmam o comportamento atual do código; especificações validam o comportamento pretendido
- As especificações em Allium e o código de reprodução do bug foram publicados no GitHub
Implicações modernas e lições
- Na época, os programadores precisavam liberar manualmente o bloqueio com as instruções
CAF ZEROeTS LGYRO- Era necessário lembrar de todos os caminhos e inserir manualmente o código de liberação
- Linguagens modernas evitam estruturalmente esse tipo de falha de recurso não liberado
- Recursos como
deferdo Go,try-with-resourcesdo Java,withdo Python e o sistema de ownership do Rust garantem liberação automática
- Recursos como
- Mesmo assim, falhas do tipo CWE-772 (liberação ausente de recurso) continuam existindo
- Conexões de banco de dados, bloqueios distribuídos, file handles e a ordem de desligamento de infraestrutura ainda continuam sendo responsabilidade do programador
- Todas as missões Apollo retornaram com sucesso, mas esse defeito permaneceu sem correção e foi herdado também pelo software COMANCHE (módulo de comando) e LUMINARY (módulo lunar)
- A falha, escondida por 57 anos, mostra a importância da análise baseada em especificação comportamental
1 comentários
Comentários no Hacker News
Sou Mike Stewart, liderei o projeto de restauração do AGC no canal CuriousMarc e sou coadministrador do VirtualAGC
O bug mencionado desta vez era de fato uma falha real no software do AGC. Mas ele não ficou abandonado durante todo o período do programa. Foi descoberto durante o teste de estágio 3 do SATANCHE, registrado como L-1D-02, e corrigido entre a Apollo 14 e a 15
Os relatórios relacionados podem ser consultados em documento 1 do ibiblio e documento 2
A correção não foi simplesmente adicionar duas linhas para zerar o LGYRO, mas incluiu também uma reestruturação da arquitetura do código e a lógica para despertar tarefas em espera. Comparando o código da Apollo 14 e da 15 (código da Apollo 14, código da Apollo 15), dá para ver a diferença
Não era um bug silencioso como descrito no artigo. O LGYRO também é inicializado em STARTSB2, que é executado sempre que há troca de programa, resolvendo o problema automaticamente. Portanto, na prática, ele só ocorria raramente ao executar o movimento de torque durante BADEND
Se o bug persistisse, várias tarefas se acumulariam e acabariam provocando o erro 31202 (uma versão posterior do 1202). Esse problema foi descoberto antes do voo da Apollo 14, e um procedimento de recuperação foi adicionado nas Apollo 14 Program Notes
Além disso, embora se diga que Ken Shirriff fez a análise em nível de portas lógicas, na prática fui eu quem fez a maior parte
O Virtual AGC concluiu a verificação de correspondência byte a byte com dumps originais de core rope apenas para alguns programas; para o conjunto completo isso ainda não é possível. A maior parte do código-fonte foi restaurada a partir de impressos ou checksums
Margaret Hamilton foi a ‘rope mother’ do Comanche (software do módulo de comando), enquanto o Luminary (módulo lunar) ficou a cargo de Jim Kernan. Isso pode ser confirmado no organograma de 1969
No momento do alarme 1202, o AGC não havia sido projetado para remover tarefas de baixa prioridade. Na verdade, a orientação de pouso era a tarefa de prioridade mais baixa, enquanto o controle da antena e a atualização do display tinham prioridade maior. Este documento resume a prioridade de cada tarefa
Por fim, testes com o hardware real confirmaram que a causa do alarme 1202 não era diferença de fase, mas sim diferença de tensão (28V vs 15V). O experimento relacionado pode ser visto neste link do YouTube
Se você tem interesse no Apollo AGC, recomendo muito o canal do YouTube CuriousMarc. Uma equipe tecnicamente brilhante documenta o processo de restaurar e analisar vários componentes do AGC
A parte especialmente interessante é a reinterpretação do infame alarme 1202. Em geral ele é apresentado como um erro de sensor que podia ser ignorado, mas na prática poderia ter sido extremamente crítico em certas condições
Meu trecho de código favorito é o seguinte
Link no GitHub
Fico curioso se já verificaram se esse bug realmente existe. A IA é boa nesse tipo de análise exploratória, mas ainda tem alta taxa de falso positivo
Dependendo do contexto, pode ser importante ou não. Também há muitos bugs que a IA não encontra
Eu não tenho a especialização para validar por conta própria, mas acho isso muito interessante
Ainda assim, a descrição da aquisição do lock e do cenário de falha pareceu bastante convincente
É interessante que eles tenham encontrado um bug real. Mas a encenação dramática do texto é quase fictícia
Coisas como bater num interruptor com o cotovelo ou exagerar um problema que seria resolvido com reset. Isso deixou o texto mais chamativo, mas menos confiável. Além disso, o estilo parece escrito por IA, o que incomoda ainda mais
Mas para explicar um bug sutil ao leitor comum, algum nível de narrativa é necessário. Se ficar técnico demais, perde o interesse; se ficar dramático demais, os especialistas criticam. Acho difícil encontrar esse equilíbrio
Eu mesmo executei o código de reprodução (repro) incluído no artigo
Link no GitHub
Ele roda, mas a Fase 5 (demonstração de deadlock) é completamente saída falsa. Em vez de rodar o emulador de verdade, ela só imprime o resultado esperado
Então enviei este PR, corrigindo para que funcione de fato no emulador, e também verifiquei se o patch de duas linhas realmente resolve o bug
Código gerado por IA tende a parar no “agora está perfeito!”, e as pessoas que acreditam nisso acabam publicando assim mesmo. Esse é o verdadeiro problema
O texto em si é interessante, mas passa uma sensação artificial de algo escrito por LLM
O fato de que até o software que levou seres humanos à Lua com apenas 4 KB de memória ainda tenha bugs não descobertos mostra como a complexidade pode se esconder até em código pequeno
Dizer que “derivaram a especificação a partir do código” está errado. Vale a pena rever o significado de specification
Tanto o artigo quanto o repositório são trabalhos descuidados (sloppy)
Se você olhar o link do repositório, a suposta “reprodução” nem executa o bug real, apenas lista mensagens de saída dizendo “isso aconteceria”