Pacman oyunundaki “seviye 256 böceği” işlenmemiş bir segfault olarak kabul edilebilir mi?


51

Birisine segmentasyon hatalarını anlatmaya çalışıyorum ve Pacman'daki 256 ekran öldürme ekranını ve tamsayı taşması ile nasıl tetiklendiğini ve davranışın bir segmentasyonda "bilinmeyen durum" ile ne kadar benzer olduğunu düşünüyordum. arıza.

Bunun “işlenmemiş segfault” dediğim şeye iyi bir örnek olduğunu söylemek isterim, ancak potansiyel olarak yanlış bilgi yaymadan önce ikinci bir görüş almayı tercih ederim.

Bakmaya çalıştım, ancak elde ettiğim tek şey hatanın kendisinin yanı sıra Hipster Whale ve Namco arasındaki kolaj.

Öyleyse, Pacman'ın 256 seviyesindeki davranışının işlenmemiş bölümlendirme ihlali örneği olduğunu düşünür müsünüz?


3
İşte böcek tam bir açıklama bunu düzeltmek için birlikte bir yama ile, var: donhodges.com/how_high_can_you_get2.htm
abligh

26
Bölümlendirme hataları, yasadışı hafıza erişimini önlemek için donanımdan kaynaklanır. Pacman konusunda uzman değilim, ancak çalıştığı donanımın kesinlikle bu güvenlik özelliğine sahip olmadığına dikkat çekti.
BlueRaja - Danny Pflughoeft

3
Wikipedia'ya göre Pacman bir Z80 kullandı. Z80'ler kesinlikle hafıza korumasına sahip değildi.
Robotu Gort

Bu bir segfault değil - sistemin herhangi bir hafıza koruması yoktu. Pac-Man'in 256 seviyesinde yaşadığı hata , oyunun kodu tarafından doğru şekilde ele alınmayan bir tamsayı taşmasıdır.
bwDraco

3
Bilginize, bunun bir hata olduğunu sanmıyorum. Hata, bir bilgisayar programında veya sisteminde hatalı veya beklenmedik bir sonuç vermesine veya istenmeyen şekillerde davranmasına neden olan başarısızlık veya hatadır. O edildi kasten kimsenin bu seviyeye alacağı hissedildi beri bu şekilde programlandı. Gerçekte, sadece zayıf yazılım tasarımı.
Keltari

Yanıtlar:


113

Kesinlikle hayır.

Ayırmadığınız bir hafıza adresine erişmek her zaman bir programlama hatasıdır. Ve bundan elde ettiğiniz bilgilere göre hareket etmek tanımsız davranışlar yaratıyor, bu kadarı doğru. Orijinal Pac-man'ın hangi platform için yazıldığını bilmiyorum ama bu davranışı diğer von Neumann makinelerinde olduğu gibi sergilediğinden eminim.

Ancak, "segmentasyon hatası", çok daha spesifik bir durum için teknik bir terimdir. Bilgisayar bunun gerçekleştiğini otomatik olarak algıladığında ve tanımsız davranışın gerçekleşmesine izin vermek yerine işlemi sonlandırdığında gerçekleşir. Bu, sofistike mülkiyet etiketlemeli özel (bölümlenmiş) bir bellek modeli gerektirir. Ben 1980 arcade oyun olduğunu vardı ve aslında oyunun davranış hatası olduğunu düşündürmektedir sanmıyorum değil algıladı ve tanımsız davranış vermedi meydana gelir.


19
@ B1KMusic: Gerçekten soruyorsun "bu kod, 'hata' sınırsız bellek erişimi yoluyla tanımsız davranışı çağırmaya bir örnek" ve cevap "evet". Bir SIGSEGV sinyali yakalama, görmezden gelme, almama ile ilgili herhangi bir rasyonalizasyon sadece kafa karıştırıcıdır.
Monica

5
@ B1KMusic tampon taşmalarının tümü bir segfault ile sonuçlanmaz. Hafızanın nasıl tahsis edildiğine bağlıdır. Hafıza statik olarak tahsis edilmişse (bir bölgeye farklı bir bölgeye elle bölünmüş büyük bir tampon) ve son seviyenin hemen arkasındaki alan bir şey için (sprite grafikler gibi) kullanılmışsa, o zaman bölmez.
mandal ucube

6
Bu eski çarşı sistemleri, DOS'un ilk sürümlerinde olduğu gibi, oyuna donanım üzerinde tam kontrol sağlayan ilkel işletim sistemleri kullandı. Bu tür bir mimaride segfault fikri bir başlangıç ​​değildir, çünkü bir çalışan sürecin (Pac-Man) tüm belleğe sahip olmadığını varsayar . Daha fazla bilgi için, bir MAME projesi ve geçmişi hakkında bilgi edinebilirsiniz .

20
Tanımsız davranış von Neumann makinelerinin bir özelliği değildir, programlama dili olan C'nin bir özelliğidir. Assembly dilinde yazılmış programlar tanımsız davranış sergilemez, çünkü assembly dili talimatlarının davranışı her zaman iyi tanımlanmıştır (sonuçlar bazen belirtilmemiş olsa bile).
Dietrich Epp

8
@Snowman bir Pac-Man makinesinde böyle bir katman yoktur. Yükleyici yok - oyun yerinde ROM'da yürütülür. Hafıza yönetimi yok - her şey statik. "Hizmet" yok; Oyun donanıma doğrudan erişir ve sistemde oyunun parçası olmayan ve oyun için yazılmış bir kod baytı yoktur.
Hobbs

38

"Tanımlanmamış davranış" ve "segmentasyon hatası" nı karıştırıyormuşsunuz gibi görünüyor.

İşlenmemiş bir segfault diye bir şey yoktur. Bir segmentasyon hatası , tanımı gereği hata işlemedir.

Kötü bellek erişimini algılayan ve güvenlik işlemini sonlandıran bir işletim sisteminiz yoksa, bir segmentasyon hatası olmaz.

Eğer bir şey, o zaman, bu UB nasıl çok iyi bir örnektir gelmez her zaman segfault sonuçlanabilir.


2
OS net olmak gerekirse olabilir (yani irrecoverably) sürecini öldürmeye karar verirler. Modern işletim sistemleri bunun yerine , FWIW olarak yakalanıp işlenebilecek olan sonlandırmayı tercih ediyor .
edmz

@black: Ben öyle demedim mi?
Monica

15
Hatta "tanımsız davranış" olmayabilir. Pacman saf derlemede yazılmışsa, kod tam olarak tanımlandığı şekilde yapması söyleneni yaptı. Tanımlanmamış davranış değil, sadece bir hata. Bu nedenle, kod, temel yonga kümesinin mükemmel bir bağlantı noktası olan herhangi bir sistemde çalışan aynı şekilde çalışır.
Robot

@StevenBurnap: Bu doğru.
Monica

@black 'Kill' ile 'terminate' arasındaki fark nedir? “Öldürme” nin normalde UNIX kelime hazinesi ve “sonlandırmak” daha çok Windows-y olduğu gerçeğinden başka?
Brandin

24

Bu terimlerden hiçbiri, assembly dilinde programlanmış ve bellek koruma donanımından veya işletim sisteminden yararlanmadan çalışan bir arcade oyunundaki bir hata için uygun değildir.

"Tanımlanmamış davranış", 1989'da geri C standartları komitesi tarafından oluşturulan C ve ilgili dillerde son teknoloji bir terimdir. Dil belirtimi ne yapacağını tanımlamadığında Kod tanımsız bir davranışa sahiptir . Z80 assembly dilinde böyle bir şey yoktur: Her bir opcode'un mümkün olan her girişle etkisi iyi tanımlanmıştır. "Tanımsız davranış" ın geleneksel İngilizce anlamı başvurmak için okunabilir - öldürme ekranı oyunu yazan insanlar tarafından tanımlanmayan davranışlardır - ancak bu bağlamda kullanmazdım çünkü yanlış vermek çok olasıdır izlenim.

"Segmentasyon hatası", PDP sistem programlama jargonundan sonuçlanan POSIX'te son teknoloji bir terimdir. Bir program herhangi bir şeyle "eşlenmemiş" bir hafıza adresine erişmeye çalıştığında bölümleme hataları meydana gelir: donanım ve işletim sistemi bunu algılar ve arızalanan programı kapatır, programın kurtarma şansını dikkatlice tanımlanmış bir şekilde sağlar . Gibi bir şeyBu Pac-Man oyun programındaki bir hata sonucu olmuş olabilir, çünkü Pac-Man devre kartı Z80'in 64kB adres alanının yarısından biraz azını ROM, RAM ve çevre birimleri ile dolduruyor, ancak ben yaptım. Yazılım eşlenmemiş belleğe erişmeye çalıştığında, gerçek donanımın ne yapacağını öğrenemedik. O yapardı ne olursa olsun (hatta ölçüde Pac-Man için "işletim sistemi", çünkü olsa da, bir "parçalama arızası" olarak tarif etmek uygun olmaz sahiptir biri) 'dir değil yine Unix bir uygulamasıdır ve, yanlış izlenim verecek.

Seviye 256 böcek, bu esnada, yok değil eşlenmemiş belleğe erişim, bu nedenle tartışmalı bulunuyor.

Oyunun 256 seviyesine ilerleyerek ortaya çıkan bir böceğe sahip olduğunu söylemek doğrudur. Ayrıca, böceğin kök nedeninin bir tamsayı taşması olduğunu ve sonuçlarının hafıza bozulma (veya eşdeğerde ihlaller) olduğunu söylemek de doğrudur. bir bellek ve tip güvenliği ). Bunların hepsi, herhangi bir dil veya işletim sistemi ortamına referans olmadan tanımlanan genel amaçlı CS terimleridir.

O gözlemlemek için de doğru olduğunu etkileri bellek bozulması böcek, modern bir ortam içinde, böcek etkilerine benzer olmayan bölme hatalarına provoke. Sıfırdan Yararlanılan Yazılanlardan herhangi birini okursanız , Don Hodges'in Pac-Man öldürme ekranı hakkındaki analizine kayda değer bir benzerlik göreceksiniz .

Pac-Man ROM'ları beslerken öldürme ekranını güvenilir bir şekilde üretmeyen bir emülatörün, oyun donanımını doğru şekilde taklit etmediğini unutmayın.


"Tanımsız davranış" ifadesi, 1989'dan önce tam olarak bu şekilde kullanılmamış olabilir, ancak bu ifadenin tanımlandığı fikri programlama kadar eskidir. Yaygın Lisp: Dil (Digital Press, 1984; ISBN 0-932376-41-X) kelimesi aynı şeyi ifade etmek için "bir hatadır" kelimesini kullandı. Örneğin, "Bu işlevi x <0 ile çağırmak bir hatadır" anlamına gelir, programcının işlevinin x <0 ile çağrılmasına izin vermemesi gerektiği ve uygulamanın kelimenin tam anlamıyla uygulayıcının yapmasını istediği herhangi bir şeyi yapmasına izin verdiği anlamına gelir. uygulama programcısı uymadı.
Süleyman Yavaş

5
@jameslarge Ne demek istediğinizi anlıyorum, ancak hala bu kavramı Pac-Man'e uygulamanın bir hata olduğunu düşünüyorum. Öldürme ekranının bir hata olduğunu söyleyebiliriz çünkü oyun tasarımcının tasarladığı gibi davranmıyor. Oyunun tanımsız davranışa neden olduğunu söyleyemeyiz , çünkü X'in herhangi bir değeri için "hiçbir koşulda programcı X yapamaz" diyecek dil belirtimi yoktur. Ayrıca oyun salonu bol yaptılar olanlar kullanabilir ve hepsi öngörülebilir etkileri vardır AFAIK).
Zwol

1
Bu en iyi cevap. "Tanımlanmamış davranış", kodlayıcının sonucun standarda dayanarak önceden bildirilemediği bir kod yazdığı anlamına gelir. Pacman Z80 derlemesinde yazıldıysa (ve sanırım öyleyse), yazılan kod, programın kodlayıcının istemediği bir şey yapıp yapmadığına bakılmaksızın tamamen tanımlanmış bir anlama sahipti.
Robotu Gort

8

Program Pac Man sonuçlarında seviye-256 hata okuma amaçlanan tablonun sonuna ötesinde olmakla verilere hala okunabilir depolama ve program yazma niyetinde olanlar dışında kalmaktadır ama olan ekranın bölümlerine yazma Yine de programın yazmasına izin verilen alanlar dahilinde . Başka hiçbir hafıza alanı etkilenmez.

Böceğin oyunu oynanamaz hale getirmesinin nedeni, makinenin ekranda ne olduğunu inceleyerek bir oyuncunun ne zaman nokta yediğini belirlemesi ve oyuncu 244 nokta yediğinde bir seviyenin tamamlandığına karar vermesidir. Ekranın bir kısmının üzerine yazıldığında, hata oyuncunun 244 nokta yemesini imkansız hale getirir; sonuç olarak oyun, oyuncuyu seviyeyi tamamlayarak asla ödünç almayacak ve ekranı noktalarla doldurmayacaktır.


1
Kendini 256 düzeyinde öldürdüğün zaman, noktalar yeniden doğar, ama hiçbirini kaybetmezsin.
Ave

@ardaozkal: Seviye çekme rutini 100'den fazla nokta siler ve birkaç çizer. Bir oyuncunun yeteri kadar yaşamı olsaydı, sonunda bir seviyeyi ilerletmek için yeterince nokta yemek mümkün olurdu, ama bu 30'dan fazla can gerektirir.
supercat,

Oyuncunun yeterli ömrüne sahip olduğu bir video izlediğimi hatırlıyorum ve o başardı ... ve daha yeni buldum .
Ave

@ardaozkal: Seviyeyi temizlemek için kaç can gereklidir ve bir oyuncu değiştirilmemiş bir makineye kaç can alabilir ?
Supercat

Değiştirilmemiş bir makinede 256 seviyeye bile ulaşamazsınız.
Ave

1

Daha önce de belirtildiği gibi bu bir seg hatası değildir. Sorunun neden ortaya çıktığını ekleyeceğim: bu bir taşma .

Seviye numarası bir baytta depolanır, bu nedenle aralık 0-255'tir. Bir seviyeyi her tamamladığınızda sayaç arttırılır. 256 seviyesinde, taşma nedeniyle sayaç aslında 0'dır.

Ancak oyun seviyenin altında bazı meyveler göstermeye çalışın. Meyve sayısı / tipi seviyeye bağlıdır. Formül, seviye 8 altındaki bitmiş seviye başına bir meyve gösterir. Sayaca göre seviye 0, yani 8'in altındadır. Test daha sonra doğrudur ve 255 meyve (eski seviye değeri) yazdırmanız gerekir. Bu imkansız ve bu parıldayan ekranı verir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.