m.t*_*ome
5
java
debugging
jpda
我有一个经典的Heisenbug例子是由我以前从未见过的情况引发的.我的遗留应用程序(大约100K旧代码)无法在特定实例中正常工作,仅仅启用JPDA进行远程调试就足以改变行为,导致应用程序正常工作:除了添加"-Xdebug -Xnoagent -Xrunjdwp之外什么都不做: transport = dt_socket,server = y,suspend = n,address = 6666"到vm的命令行隐藏了bug(有或没有实际连接).鉴于我有一个完全可重复的测试用例,我讨厌在代码更改的情况下对其进行干扰,以防它重新隐藏.当然,这只发生在生产中.
通常,我会立即假设一个线程问题,但是a)行为是100%失败与100%工作,b)在相关代码路径中没有明确使用线程.然后我们的团队试图找出这种行为的其他原因列表,所以我想也许Stack Overflow的团队思想可能会增加更多.
Java中的Heisenbugs:
- 线程:错误的同步,竞争条件,隐式排序假设.
- 显式调试/日志记录代码:代码路径中的更改导致/防止出现问题.不太常见的是,日志级别的更改可能导致时序更改(再次线程化)和I/O资源使用的差异.
- 本机代码库可以拖入非Java Heisenbug问题.
- 期待终结者以可预测的方式运行.
- 关于弱引用的不恰当假设.
- 假设固定大小的缓存永远不会填充.
- 期待哈希码的唯一性.
- 假设==适用于字符串(或者不适用于可能在某些情况下被中断的字符串).
- VM bug(不,那从未发生过;).
- 测试方法错误.特别是当存在依赖于测试成功的隐藏变量时.(这看起来是我们的实际问题.一次测试的成功导致客户运行下一次测试,由于策略问题而失败.失败导致根据策略在调试模式下运行,这导致成功.叹气)
还有其他值得探索的案例吗
编辑:
- 是的,JPDA启用代码使用旧语法.我没有测试过使用现代语法是否也会改变行为.
- 这台特定的机器使用1.8.0_45-b14作为JRE,HotSpot 64位服务器VM(版本25.45-b02)
- 虽然问题是一般的,但鼓动的问题是真实的和最新的.由于这个问题在已部署的系统中出现,我想要让它与-Xdebug一起运行作为一种解决方法,以便它保持运行并希望跟踪底层错误并将其杀死.
- 有问题的故障程序是多步骤数据处理管道的一部分 - 细节无关紧要,但可以最好地理解为从数据库获取一些信息然后用它来修改某些文件的独立应用程序.系统中破坏的部分似乎是来自数据库的信息没有被正确解释 - 来自破坏的对象ORM或缓存的任何东西.当它"被破坏"时,确定它是否有工作要做的应用程序逻辑(基于db的内容)对所有迭代(数千次迭代,包括程序的多次调用)做出错误的选择.当它"工作"时(唯一的区别是vm与-Xdebug一起运行),应用程序为所有迭代做出正确的选择.它在此配置中完全一致.针对不同数据库运行的相同代码不会失败.有一些证据(在我参与此代码之前)已经看到类似的行为,在看似微小的代码变化之后神秘地开始工作......参见"Heisenbug"