如果调试行为与正常执行不同,该怎么办?

11

我在调试会话中遇到了问题。 我的程序在调试会话中执行得非常好,但如果我开始正常运行,它的行为就完全不同。
问题是我不能确定为什么会有差异。

可能的原因之一是执行时间较慢,因为您总是需要按F6或类似键。
我尝试插入 Thread.sleep(1000); ,但我不知道引起不同行为的指令。

那么:有哪些提示和最佳实践可以了解为什么在调试会话中表现如此不同?


你怎么能同时拥有一个与语言无关的标签和Java标签,这有点自相矛盾。 - UnkwnTech
我考虑使用[java]标签,因为我认为我需要更详细地介绍我的程序并指定使用Java。但实际上这并不是必要的,所以我删除了这个标签。 - guerda
语言在这个问题中有一定的相关性。我会将与语言无关的内容保留给设计问题、需求等。 - Daniel Daranas
2
完全离题,但感谢您展示 <kbd> 标签,我不知道 SO 支持它。很好! - unwind
7个回答

11

两种解决方案:

a) 使用简易的调试工具(打印到控制台)或使用日志框架,当出现错误时,分析输出信息。

b) 编写测试用例以尝试重现问题。即使您无法通过此方法找到问题,这也可以清理代码并有时解决问题。


1
如果问题确实是由竞态条件引起的,那么记录日志式调试只会让情况更加混乱。如果问题不是由此引起的,那么你的方式可能是最好的。 - pmr
java.io.PrintStream.println(String) 调用同步,这会导致延迟等问题(例如,在你调试的资源上竞争?)。因此,即使是简单的调试器也可能会产生意想不到的副作用。请参见:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/io/PrintStream.java#PrintStream.println%28java.lang.String%29 - Dan Barowy

6

如果没有减缓执行速度的调试语句,您可能会观察到仅在这种情况下发生的竞争条件。从审查线程模型开始,并注意任何可能的锁定可能会有所帮助。


有关死锁,请参见http://www.javaspecialists.eu/archive/Issue093.html。 - Aaron Digulla

3

我试图检查我的假设并再次检查它们。

过度记录在某些情况下可能有所帮助,但并非总是如此。在我的情况下,并没有帮助太多。
使用记录,您可以看到您的假设正确的地方和哪些失败了。

我的个人解决方案是针对Java的特定情况。自JDK 1.5以来,Java ClassLoader不会完全加载类。在调试会话中,必须完全加载。因此,某些变量未初始化良好,输出与正常运行不同。
这个原因很难找到。


你为什么要像两个不同的人一样回答自己? - Daniel Daranas
1
我能用另一种方式回答它吗?我想象中的stackoverflow,这可能对其他用户有帮助。 - guerda
不,我不知道。我正在寻找可能在这种情况下有用的提示。所有这些答案都可能有帮助。 - guerda
1
我认为你自己的提示应该列在问题中,而不是添加为答案。 - l3dx
1
这些都是非常基础的策略,应该在您的回答中列出,例如“我已经尝试过……”。否则这看起来有点像比赛。 - Daniel Daranas

2

调试多线程应用程序确实很困难。

你可以尝试使用旧的System.out.println技术进行调试,而不是使用调试器...也许这样可以在具有你提到的不同行为时进行调试。

Manu


0

注意:不一定与多线程相关。

有时候,为我解决问题的方法是设置不同的断点。

有时候,评估值会改变它们的值(例如读取迭代器的值)。
其次,您的“错误”断点可能会阻碍并行性和竞争条件。


0

首先检查一些简单的东西。崩溃版本是否获得相同的命令行参数?或特殊环境变量?或用户ID?或其他你知道很重要的因素。换句话说,你是否真的使用相同的输入运行它。

它是否总是崩溃?它是否在同一个地方崩溃?如果你可以在崩溃后连接调试器,那么它停止工作的地方可能会提供一些线索。最近的某些更改是否可能是罪魁祸首?如果是这样,请尝试删除它并观察发生了什么。

不要过于纠结于这些尝试。它们只是猜测,如果能够快速解决问题就很好,但最终是无效的,因为“在调试状态下运行”和“自由运行”之间有数百万种可能的差异。

否则,切断差分分析并解决问题。也就是说,直接查看崩溃时出现的问题,而不是迭代可能的原因。

以下是一些书籍摘录,可能会帮助您“在没有调试器的情况下进行调试”。

《编程实践》中的第5章“调试”

《寻找最难定位的软硬件问题九条不可或缺的规则》中的9个规则

祝你好运!


0

我遇到了类似的问题。

我的问题是:Set.iteratordebugrun 中产生了不同的结果。

当然,我的代码存在一个错误,间接地依赖于集合元素的顺序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接