Estou tentando explicar as falhas de segmentação para alguém, e estava pensando sobre o kill-screen de nível 256 no Pacman, como é acionado pelo excesso de números inteiros e como o comportamento é semelhante ao "estado desconhecido" frequentemente descrito em uma segmentação. culpa.
Quero dizer que este é um bom exemplo do que chamo de "falha não tratada", mas prefiro ter uma segunda opinião antes de potencialmente espalhar informações erradas.
Tentei procurar, mas tudo o que estou conseguindo são documentos sobre o bug em si, bem como sobre a colaboração entre Hipster Whale e Namco.
Então, você consideraria o comportamento no nível 256 do Pacman um exemplo de violação de segmentação não tratada?
Respostas:
Definitivamente não.
Acessar um endereço de memória que você não alocou é sempre um erro de programação. E agir de acordo com as informações que você obtém produz um comportamento indefinido, isso é preciso. Não tenho idéia para qual plataforma o Pac-man original foi escrito, mas tenho certeza de que exibiu esse comportamento como qualquer outra máquina de von Neumann.
No entanto, "falha de segmentação" é um termo técnico para uma condição muito mais específica. Isso acontece quando o computador detecta automaticamente que isso aconteceu e finaliza o processo, em vez de permitir que comportamento indefinido ocorra. Isso requer um modelo de memória específico (segmentado) com marcação de propriedade sofisticada. Eu não acho que 1980 jogos de arcade tinha isso, e de fato o comportamento do jogo sugere que o erro foi não detectada e o comportamento indefinido que ocorrem.
fonte
Parece que você está confundindo "comportamento indefinido" e "falha de segmentação".
Não existe um segfault não tratado. Uma falha de segmentação é o tratamento de erros, por definição.
Se você não possui um sistema operacional que detectou o acesso ruim à memória e encerrou o processo por segurança, não há uma falha de segmentação.
Se houver algo, então, este é um bom exemplo de como o UB nem sempre resulta em um segfault.
fonte
Nenhum desses termos é apropriado para um bug em um jogo arcade programado em linguagem assembly e executado sem o benefício de hardware ou sistema operacional de proteção de memória.
"Comportamento indefinido" é um termo de arte em C e linguagens relacionadas, cunhado pelo comitê de padrões C em 1989. O código tem um comportamento indefinido quando a especificação de linguagem não define o que fará. Não existe tal coisa na linguagem assembly Z80: o efeito de todo código de operação com todas as entradas possíveis é bem definido. O significado convencional em inglês de "comportamento indefinido" pode ser lido para aplicar - a tela de morte é um comportamento não definido pelas pessoas que escreveram o jogo - mas eu não o usaria neste contexto porque é muito provável que dê errado impressão.
"Falha de segmentação" é um termo de arte no POSIX, derivado em última análise do jargão de programação do sistema PDP. As falhas de segmentação acontecem quando um programa tenta acessar um endereço de memória que não é "mapeado" para nada: o hardware e o sistema operacional detectam isso e encerram o programa com defeito, de uma maneira cuidadosamente definida que permite ao programa a chance de se recuperar . Algo comoisso pode ter acontecido como resultado de um bug no programa de jogos Pac-Man, porque a placa de circuito Pac-Man ocupa apenas um pouco menos da metade do espaço de endereço de 64kB do Z80 com ROM, RAM e periféricos, mas eu não Não foi possível descobrir o que o hardware real faria se o software tentasse acessar a memória não mapeada. Seja o que for, seria inapropriado descrever como uma "falha de segmentação", porque o "sistema operacional" do Pac-Man (na medida em que possui um) não é uma implementação do Unix e, novamente, ele daria a impressão errada.
O bug do nível 256, enquanto isso, não acessa a memória não mapeada, por isso é discutível.
É preciso dizer que o jogo possui um bug que se manifesta ao avançar para o nível 256. Também é preciso dizer que a causa raiz do bug é um estouro de número inteiro e que suas conseqüências são corrupção de memória (ou, equivalentemente, violações) de memória e tipo de segurança ). Todos esses termos de uso geral são definidos sem referência a um idioma ou ambiente de SO específico.
Também é preciso observar que os efeitos do bug são semelhantes aos efeitos, em um ambiente moderno, de erros de corrupção de memória que não provocam falhas de segmentação. Se você ler algum dos escritos de exploração do Project Zero , verá uma notável semelhança com a análise de Don Hodges da tela de morte do Pac-Man .
Observe que um emulador que não reproduz fielmente a tela de morte quando alimentado com as ROMs do Pac-Man não está emulando o hardware do jogo corretamente.
fonte
O bug de nível 256 no Pac Man resulta na leitura de dados do programa que está além do final da tabela pretendida, mas ainda é um armazenamento legível e na gravação de partes da tela que estão além daquelas que o programa pretende gravar, mas são ainda bem dentro das áreas da tela que o programa está autorizado a escrever . Nenhuma outra área da memória é afetada.
A razão pela qual o bug torna o jogo impossível de jogar é que a máquina determina quando um jogador está comendo pontos examinando o que está na tela e decide que um nível está completo quando o jogador comeu 244 pontos. Ao sobrescrever parte da tela, o bug torna impossível para o jogador comer 244 pontos; consequentemente, o jogo nunca creditará ao jogador a conclusão do nível e recarregará a tela com pontos.
fonte
Como disse antes não, não é uma falha seg. Vou acrescentar por que o problema ocorre: é um estouro .
O número do nível é armazenado em um byte, portanto o intervalo é de 0 a 255. Cada vez que você completa um nível, o contador é incrementado. No nível 256, o contador é de fato 0 devido ao estouro.
No entanto, o jogo tenta exibir algumas frutas na parte inferior do nível. O número / tipo de fruta depende do nível. A fórmula exibe uma fruta por nível final abaixo do nível 8. De acordo com o contador, você está no nível 0 e abaixo do 8. O teste é verdadeiro e você precisa imprimir 255 frutas (o valor do nível antigo). O que é impossível e fornece essa tela com falha.
fonte