吃豆人游戏中的“ 256级错误”可以被视为未处理的段错误吗?


51

我试图向某人解释分段错误,并且我正在考虑吃豆子中的256级杀伤屏幕,整数溢出是如何触发的,以及该行为与分段中经常描述的“未知状态”有多相似故障。

我想说的是这是我所谓的“未处理的段错误”的一个很好的例子,但是在我可能散布错误信息之前,我宁愿先获得第二意见。

我尝试查找它,但我得到的只是有关错误本身的文档,以及Hipster Whale和Namco之间的协作。

因此,您是否认为Pacman级别256中的行为是未处理的细分违规的示例?


3
下面是错误的精确描述,一个补丁一起解决它:donhodges.com/how_high_can_you_get2.htm
abligh

26
硬件会引发分段错误,以避免非法的内存访问。我不是吃豆人的专家,但是运行它的硬件几乎可以肯定没有该安全功能。
BlueRaja-Danny Pflughoeft

3
根据维基百科,吃豆子使用的是Z80。Z80s绝对没有内存保护。
Gort Robot

这不是段错误-系统没有任何形式的内存保护。吃豆人在256级遇到的错误仅仅是游戏代码无法正确处理的整数溢出。
bwDraco '16

3
仅供参考,我认为这不算是错误。错误是指计算机程序或系统中的故障或错误,导致其产生不正确或意外的结果,或行为异常。有人以这种方式对此进行了有计划的编程,因为有人认为没有人会达到这一水平。实际上,它只是糟糕的软件设计。
Keltari '16

Answers:


113

当然不。

访问未分配的内存地址始终是编程错误。根据从中获得的信息采取行动会产生不确定的行为,这是非常准确的。我不知道最初的吃豆人是为哪个平台编写的,但是我很确定它像其他任何冯·诺依曼机器一样表现出这种行为。

但是,“分段故障”是更特定条件的技术术语。当计算机自动检测到这种情况并终止进程而不是允许发生未定义的行为时,就会发生这种情况。这需要具有复杂所有权标记的特定(分段)内存模型。我认为1980年的街机游戏不具备这种功能,实际上游戏的行为表明检测到错误,并且确实发生了未定义的行为。


19
@ B1KMusic:您实际上是在问“此代码是否“ bug”是通过越界内存访问来调用未定义行为的示例”,答案是“是”。关于捕获,忽略而不得到SIGSEGV信号的任何合理化都只会使事情变得混乱。
与莫妮卡(Monica)进行的轻度比赛

5
@ B1KMusic并非所有缓冲区溢出都会导致段错误。这取决于如何分配内存。如果内存是静态分配的(一个大缓冲区手动拆分到不同的区域),并且紧接在最后一级后面的区域用于某些内容(如精灵图形),则不会出现段错误。
棘轮怪胎

6
那些旧的街机系统使用原始的OS,可以使游戏对硬件进行完全的控制,类似于DOS的早期版本。在这类型的架构段错误的想法是一个非首发,因为它假设了一个正在运行的进程(吃豆人),并没有自己的所有内存。有关更多信息,可以阅读MAME项目及其历史。

20
未定义的行为不是von Neumann机器的属性,而是编程语言C的属性。用汇编语言编写的程序不能表现出未定义的行为,因为汇编语言指令的行为始终是良好定义的(即使有时未指定结果)。
Dietrich Epp

8
@Snowman在Pac-Man机器上没有这样的层。没有加载程序-游戏位于就地执行ROM中。没有内存管理-一切都是静态的。没有“服务”;游戏直接访问硬件,并且系统上没有属于游戏的一部分并没有为游戏编写的代码字节。
hobbs

38

您似乎在混淆“不确定的行为”和“细分错误”。

没有未处理的段错误。根据定义,分段错误错误处理。

如果您没有操作系统检测到错误的内存访问并为安全起见终止了该过程,那么您就不会遇到分段错误。

如果有的话,这是UB 并非总是导致段错误的一个很好的例子。


2
准确地说,操作系统可能决定终止(即不可恢复)该过程。相反,现代操作系统更喜欢终止它,FWIW可能会捕获并处理它。
edmz

@black:那不是我说的吗?
与莫妮卡(Monica)进行的轻度比赛

15
它甚至可能不是“未定义的行为”。如果Pacman是用纯汇编语言编写的,那么代码完全按照完全定义的方式完成了它的工作。不是未定义的行为,而只是一个错误。这样,代码将以完全相同的方式在具有基础芯片组完美端口的任何系统上运行。
Gort Robot

@StevenBurnap:是的。
与莫妮卡(Monica)进行的轻度比赛

@black“ kill”和“ terminate”有什么区别?除了“ kill”通常是UNIX词汇,而“ terminate”是Windows-y事实以外?
布兰丁

24

这两个术语都不适合用汇编语言编程且无法在没有内存保护硬件或操作系统的情况下运行的街机游戏中的错误。

“未定义行为”是一个术语的最先进的C和相关语言,由C标准委员会早在1989年创造的代码已未定义行为时,语言规范没有定义什么都行。Z80汇编语言中没有这样的东西:每个操作码对每个可能的输入的影响都是明确定义的。可以理解为英语中“未定义行为”的常规含义适用-终止屏幕是写游戏的人未定义的行为-但我不会在这种情况下使用它,因为它很可能会给出错误的信息印象。

“分段故障”是POSIX中的一个术语,最终源自PDP系统编程术语。当程序尝试访问未“映射”到任何内容的内存地址时,就会发生分段错误:硬件和操作系统会以一种精心定义的方式检测到此错误并关闭有故障的程序,从而使程序有机会恢复。什么这可能是由于吃豆人游戏程序中的错误导致的,因为吃豆人电路板仅使用ROM,RAM和外围设备填充了Z80 64kB地址空间的一半以下,但我还没有这样做。如果软件试图访问未映射的内存,我们将无法找到真正的硬件会做什么。但是,无论做什么,将其描述为“分段错误”都是不合适的,因为Pac-Man的“操作系统”(甚至一个操作系统)不是 Unix的实现,并且它也是会给人留下错误的印象。

同时,级别256的错误不会访问未映射的内存,因此很无聊。

准确地说,游戏中存在一个错误,该错误会在升至256级时出现。准确地说,该错误的根本原因是整数溢出,其后果是内存损坏(或等效地,违规)。的存储器和类型安全)。这些都是通用CS术语,定义时未参考任何特定语言或OS环境。

这也是准确的观察到效果的bug是类似的效果,一个现代化的环境中,内存腐败的bug 惹段故障。如果您阅读了Project零漏洞利用报告中的任何内容,您将发现与Don Hodges 对《吃豆人》杀戮屏幕分析极为相似。

请注意,模拟器在喂饱吃豆人ROM时不能如实地再现终止屏幕,这不能正确地模拟游戏硬件。


“未定义行为”一词在1989年之前可能还没有以这种确切的方式用于印刷中,但是该词描述的思想与编程本身一样古老。 Common Lisp:语言(Digital Press,1984; ISBN 0-932376-41-X)使用“这是一个错误”一词来表示完全相同的意思。例如,“使用x <0调用此函数是一个错误”,这意味着程序员不应允许使用x <0调用该函数,并且如果实现了该实现,则该实现实际上可以执行实现者希望它执行的任何操作应用程序程序员不遵守。
所罗门慢

5
@jameslarge我理解您的意思,但是我仍然认为将此概念应用于吃豆人是错误的。我们可以说杀死屏幕是一个错误,因为游戏显然不符合设计者的预期。我们不能说游戏引起了未定义的行为,因为没有语言规范说“在任何情况下程序员都不能对X赋X”。很多街机游戏的确使用了它们和AFAIK,它们都有可预测的效果。)
zwol 2016年

1
这是最好的答案。“未定义的行为”是指编码器根据标准无法预测其结果的代码。如果Pacman是用Z80汇编语言编写的(我相信是这样),那么所编写的代码将具有完全定义的含义,而不管该程序是否执行了编码器不希望的操作。
Gort Robot

8

Pac Man中的256级错误导致程序读取的数据超出了预期表的末尾,但可读的存储,并且写入了屏幕上超出程序意图写入但超出预期范围的部分仍然在允许程序编写的屏幕区域内。不会影响其他内存区域。

该错误使游戏无法进行游戏的原因是,该机器通过检查屏幕上的内容来确定玩家何时在吃点,并在玩家吃掉244点后判定等级是否完整。通过覆盖部分屏幕,该错误使玩家无法吃掉244点;因此,游戏将永远不会为完成关卡而使玩家信服,也不会用点重新载入屏幕。


1
当您在256级杀死自己时,这些点会重生,但不会丢失任何点。
2016年

@ardaozkal:水平绘制例程会擦除100个以上的点,并绘制一些点。如果玩家有足够的生命,那么最终有可能吃掉足够多的点来提升关卡,但这将需要30多个生命。
超级猫

我记得在观看视频时,播放器有足够的生命,而他却管理了……我才发现它
2016年

@ardaozkal:清除关卡需要多少生命,并且玩家可以在未经修改的机器上获得多少生命?
超级猫

在未经修改的计算机上,您甚至无法达到256级。
2016年

1

如前所述,这不是段错误。我将添加问题发生的原因:这是一个溢出

级别号存储在一个字节上,因此范围是0-255。每次完成一个级别,计数器都会递增。在256级,由于溢出,计数器实际上为0。

但是,游戏尝试在关卡底部显示一些水果。水果数量/类型取决于水平。该公式在级别8下每个完成的级别显示一个水果。根据计数器,您在级别0上因此在级别8之下。那么测试为true,则必须打印255个水果(旧级别值)。这是不可能的,并且会出现此故障屏幕。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.