什么是heisenbug:术语和示例的历史

这是有关Heisenbags的参考资料。 我们正在谈论它们的外观以及它们与大型机(云的始祖)之间的关系。


/图片Lars Zimmermann CC BY

Heisenbug (Heisenbug或Heisenbug)是一个术语,描述了在代码调试过程中更改属性的错误。 也就是说,它们在测试和调试期间消失,但​​在生产中出现。

“海森巴格”这个名字是指海森堡量子力学的不确定性原理 。 一般而言,可以将其描述为观察结果导致观察对象特性的意外变化。

故事


Heisenbug一词被认为是IBM研究中心的员工Bruce Lindsay。 他为关系数据库的开发做出了贡献,并参与了IBM System R企业数据库引擎的开发。

1985年,在美国伯克利大学学习期间,布鲁斯和吉姆·格雷 (James Nicholas Gray)(美国计算机系统理论的科学家)研究了OS CAL-TSS。 它是为Control Process 6400双处理器大型机[ PDF ,第3页]专门编写的,军方在该主机上处理了大量数据。

当然,在开发过程中会出现错误。 但是其中有几个很特别-工程师试图修复它们后,它们就消失了。 当时,林赛只是在研究物理学,尤其是海森堡原理。 突然,它出现在Lindsay身上-他和Gray看到了类似的现象:错误消失了,因为观察影响了物体的特性。 从这里起名为“ heisenbag”。

Lindsay在2003年接受 计算机工程协会 (ACM)代表的采访时讲述了这个故事。

Heisenbug的例子


网络和主题平台(例如Stack Overflow)上的用户分享了他们在项目中遇到的heisenbags的一些示例。 一位SO居民试图计算两条曲线之间的图形面积,精确度为小数点后三位。 为了调试C ++中的算法,他添加了以下代码:

cout << current << endl; 

但是,一旦他对此发表评论,代码便停止工作并循环。 该程序如下

 #include <iostream> #include <cmath> using namespace std; double up = 19.0 + (61.0/125.0); double down = -32.0 - (2.0/3.0); double rectangle = (up - down) * 8.0; double f(double x) { return (pow(x, 4.0)/500.0) - (pow(x, 2.0)/200.0) - 0.012; } double g(double x) { return -(pow(x, 3.0)/30.0) + (x/20.0) + (1.0/6.0); } double area_upper(double x, double step) { return (((up - f(x)) + (up - f(x + step))) * step) / 2.0; } double area_lower(double x, double step) { return (((g(x) - down) + (g(x + step) - down)) * step) / 2.0; } double area(double x, double step) { return area_upper(x, step) + area_lower(x, step); } int main() { double current = 0, last = 0, step = 1.0; do { last = current; step /= 10.0; current = 0; for(double x = 2.0; x < 10.0; x += step) current += area(x, step); current = rectangle - current; current = round(current * 1000.0) / 1000.0; //cout << current << endl; //<-- COMMENT BACK IN TO "FIX" BUG } while(current != last); cout << current << endl; return 0; } 

heisenbug的本质 :当没有打印输出时,程序将在处理器寄存器中以较高的精度执行比较。 而且,结果的准确性超过了两倍的能力。 为了输出该值,编译器将计算结果返回到主存储器-小数部分被丢弃。 而while中的后续比较将得出正确的结果。 当注释掉一行时,小数部分没有隐式的截断。 因此,while中的两个值总是相互不相等。 作为该问题的解决方案,讨论中的一位参与者建议使用浮点数的近似比较。

在Unix上使用Smalltalk-80语言环境的工程师分享了有关heisenbug的另一个故事。 他们注意到,如果您将系统闲置一会儿,系统就会崩溃。 但是在移动鼠标光标之后,所有操作仍照常进行。

问题出在Unix调度程序上,它降低了空闲任务的优先级。 在某些时候,优先级降低了很多,以至于Smalltalk中的过程没有时间来完成。 任务堆栈增长并挂起了程序。 当用户移动光标时,操作系统恢复了优先级,并且所有内容均恢复为平方。

其他*错误


有许多术语可以描述各种错误:Borbag​​,Mandelbug和Schrödinbag。

与Heisenbug相对的Borbag是一个常见错误,很容易找到和修复。 以尼尔斯·玻尔(Niels Bohr)的名字命名,他于1913年提出了一个简单易懂的原子结构模型。 根据该模型,原子的电子在某些轨道上运动,这意味着可以预测它们的动量和运动半径。 同样,如果为Borbag​​s创建了必要的条件,则可以预测它们的外观。


/ ORNL CC BY的OLCF照片

Schroedinbag是一个错误,在开发人员查看之前,它同时存在和不存在。 该错误是为了纪念一个著名的思想实验而命名的。

对于Mandelbug而言 ,这是一个错误,由于该错误导致系统行为不稳定且无法预测。 这种现象以分形几何学Benoit Mandelbrot的物理学家,数学家和创造者命名。

结果如何


很多 Heisenbags的示例(以及其他*错误)。 它们很难找到,但是原因通常很常见:未初始化的变量,多线程环境中的同步错误或无效代码删除算法的问题。 事实证明,为了处理此类错误,即使在应用程序设计阶段也需要将其消除。



来自公司的IaaS博客:

Source: https://habr.com/ru/post/zh-CN448002/


All Articles