海森堡bug

在程序设计术语中，海森堡bug（）是指在尝试研究它时似乎会消失或者改变行为的bug（程序错误）。该词汇是关于物理学家维尔纳·海森堡名字的双关语，他最先断言了量子力学的观察者效应——观察系统的行为将不可避免地将改变其状态。电子学中的传统用语则是，指连接一个到设备将改变其行为。

类似的词语有玻尔bug（bohrbug）、曼德博bug（mandelbug）和薛定谔bug（schrödinbug），它们偶尔被用于指代其他类型的非寻常软件缺陷，但通常以开玩笑的心态使用。

例子 
之所以会出现海森堡bug，是因为通常的调试手段，诸如插入输出语句或是挂接调试器，往往会修改程序代码，或是更改变量的内存地址，或是改变其执行时间。这都可能影响程序的行为。如果正好影响到了bug，就有可能产生海森堡bug。

海森堡bug的一个常见情况是，bug只在打开編譯器优化时出现，而关闭优化再编译程序（使用调试器时通常如此）则bug消失。一些在优化后的程序中通常会放入寄存器的值，在调试状态下会放入到主内存。这会造成一些影响，比如这可能会影响浮点数比较的结果，因为内存中的值可能比寄存器中的值有更小的范围和精度。与此类似，C、C++等语言中使用的运行时断言的副作用可能导致海森堡bug，因为当生产环境的代码使用NDEBUG宏关闭断言后，测试表达式不会被求值。

海森堡bug的其他常见原因是使用未初始化的变量的值（调试时此变量的初始值或地址可能有变化），或者使用了指標（调试时可能指向了不同的地方）。调试器也经常提供监视器(watches)或其他用户界面，它们也可能添加额外的源代码来隐秘地执行（例如属性存取器），从而改变程序的状态。

时间也可能是海森堡bug的一个因素，尤其是对于多线程应用程序而言。在调试器控制下执行的程序与正常执行的程序在运行时间上会有差异。使用调试器进行逐行单步调试时，时间敏感的bug（例如競爭危害）可能不会发生。当行为涉及到与不在调试器控制下的实体进行交互时，例如两台计算机之间的网络数据包处理时，则更是如此。

海森堡bug可以被视为的一个实例。沮丧的程序员可能会幽默地指责一个海森堡bug是由于月相或其他因素，或者猜测它是因为Α粒子或宇宙線影响计算机硬件而导致的軟性錯誤所致（如果只发生了一次）。

相关词汇 
词汇“bohrbug”是海森堡bug的一个反义词，它指良好、稳定的bug。就像确定性的玻尔模型一样，它们不改变自己的行为，并且相对容易被检测到。

曼德博bug（mandelbug，名字取自本華·曼德博的曼德博集合）是原因极其复杂而很难修复的bug，其行为看上去混乱甚至存在不确定性。它也指程序员深入检查代码、修复它们时会发现更多bug的bug。

薛定谔bug（schrödinbug，名字取自埃尔温·薛定谔及他的薛定谔猫）是程序员发现一个永远不应该被触发的情况发生的bug。

兴登堡bug（hindenbug，名字取自興登堡號空難）是具有灾难性行为的bug。

希格斯bug子（higgs-bugson，名字取自希格斯玻色子）是一个基于观测到的条件（最常见的是模糊相关的日志项和似是而非的用户报告），而预计会出现的bug，但它几乎不可能在开发过程和测试环境下重现。这个词也可能指代一个在代码中的明显bug（被数学验证），但是在执行中无法观察到，或是难以在实际执行中发现。

词汇历史 
该词汇在1985年被詹姆斯·尼古拉·格雷在一篇关于软件故障的论文中使用，并也在1986年由Jonathan Clark和Zhahai Stewart在邮件列表（之后的Usenet新闻组）中使用。

供职于IBM的研究员在2004年的采访中确认，Heisenbug被最初定义时他在场。

更早它于1983年在ACM的出版物中有出现。

解决 
海森堡bug难以被发现和修复，而且在尝试修复它的时候经常会引起更多意料之外的程序行为。原因是这种问题的出现通常是由另外一个bug为其提供支撑，使程序行为在调试过程中难以预测和分析。总体来看，随着软件的成熟，海森堡bug的数量将会减少。

参见 
 货物崇拜编程
小黄鸭调试法
 —一种用于检测和重现Heisenbug的工具（Windows）
 
 —一种自动探测可能导致Heisenbug的工具。

参考资料

外部链接 
 The Heisenberg Debugging Technology 
 A Story About Magic
 OpenOffice won't print on Tuesdays ，一个令人着迷的海森堡bug，花费了将近九个月的时间来解决。
 消灭神出鬼没的Heisenbug 

调试
程式錯誤
软件测试