微处理器具有针对各种故障情况的陷阱。它们是同步中断,允许正在运行的操作系统/软件对错误采取适当的措施。陷阱中断程序流程并设置寄存器位以指示故障。调试器断点也使用陷阱实现。
在典型的计算环境中,操作系统负责处理由用户进程触发的 CPU 陷阱。让我们考虑一下当我运行以下程序时会发生什么:
int main(void)
{
volatile int a = 1, b = 0;
a = a % b; /* div by zero */
return 0;
}
显示了一条错误消息,我的盒子仍在运行,就像什么都没发生一样。在这种情况下,我的操作系统处理故障的方法是杀死有问题的进程并通过错误消息Floating point exception 通知用户。
内核模式下的陷阱问题更大。如果操作系统本身有错误,则操作系统采取纠正措施并不那么简单。对于系统进程,没有底层保护。这就是为什么有缺陷的设备驱动程序会导致真正的问题。
在裸机上工作时,没有操作系统的舒适保护,情况与上述情况非常相似。实现连续和正确操作的首要目标是使用断言和更高级别的错误处理程序在触发任何陷阱之前捕获所有潜在的陷阱条件。 将陷阱视为最后一道防线,一个您不想陷入的安全网。
为陷阱处理程序定义行为值得深思,即使它们“不应该发生”。当事情以意料之外的方式出现问题时,它们将被执行,因为在最极端的情况下宇宙射线会改变 RAM。不幸的是,对于错误处理程序应该做什么,没有一个正确的答案。
代码完成,第二版:
最合适的错误处理方式取决于发生错误的软件类型,通常更倾向于正确性或更稳健性。严格来说,这些术语彼此处于相对的两端。正确性意味着永远不会返回不准确的结果;没有结果比不准确的结果更好。稳健性意味着始终尝试做一些可以让软件继续运行的事情,即使这有时会导致结果不准确。
显然,我的操作系统的故障处理在设计时考虑到了稳健性;我可以执行有缺陷的代码并做几乎任何事情而不会导致系统崩溃。仅针对稳健性进行设计将意味着尽可能进行恢复尝试,如果其他所有方法都失败,则重置。如果您的产品是,例如,这是一种合适的方法。一个玩具。
对安全至关重要的应用程序需要更多的偏执狂,应该更倾向于正确性;当检测到故障时,写入错误日志,关机。我们不希望我们的放射治疗单元从无效的垃圾值中挑选剂量水平。