java - 如何在 Java 中跟踪值的来源?

标签 java debugging

我有一个很少得到不正确值的变量。由于系统非常复杂,我无法跟踪值经过的所有代码路径 - 涉及多个线程,它可以保存然后从数据库加载等等。我将尝试使用代码图生成器来查看是否可以通过查看调用 setter 的方式来发现问题,也许还有其他一些技术。也许用一个跟踪它所经历的地方和变化的类来包装值(value)?我不确定这个问题是否足够清楚,但我很感激遇到这种情况的人的意见。

[编辑] 这个问题不容易重现,我无法在调试器中发现它。我正在寻找一种静态分析或日志记录技术来帮助追踪问题。

[编辑 2] 为了让事情更清楚,我所说的值是一个时间戳,表示为 64 位长变量中从 Unix 纪元 (01/01/1970) 开始的毫秒数。在某个未知点,值的前 32 位被截断,生成完全不正确(且不可恢复)的时间戳。

[编辑 3] 好的,感谢您的一些建议和几个小时的代码倾注,我找到了罪魁祸首。通过将基于毫秒的时间戳除以 1000 并将其存储在 int 变量中,将基于毫秒的时间戳转换为基于秒的时间戳。在稍后的代码中,基于秒的时间戳(一个 int)乘以 1000 并存储到一个新的 long 变量中。由于 1000 和基于秒的时间戳都是 int 值,乘法的结果在转换为 long 之前被截断了。感谢所有提供帮助的人。

最佳答案

如果您使用一个 setter 并且只使用一个 setter 来设置您的值,您可以添加这些行以跟踪线程和堆栈跟踪:

public void setTimestamp(long value) {
  if(log.idDebugEnabled) {
    log.debug("Setting the value to " + value + ". Old value is " + this.timestamp);
    log.debug("Thread is " + Thread.currentThread().getName());
    log.debug("Stacktrace is", new Throwable()); // we could also iterate on Thread.currentThread().getStackTrace()
  }
  // check for bad value
  if(value & 0xffffffff00000000L == 0L) {
    log.warn("Danger Will Robinson", new IlegalValueException());
  }
  this.timestamp = value;
}

此外,检查包含该字段的类,并确保对它的每个引用都是通过 setter 完成的(即使是在私有(private)/ protected 方法中)

编辑

也许 FindBugs可以在静态分析方面提供帮助,我稍后会尝试找到确切的规则。

关于java - 如何在 Java 中跟踪值的来源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1620786/

相关文章:

java - 与线程一起使用的音乐库

c# - 有没有办法在 C# 中捕获调试消息,然后将它们输出到单独的窗口?

python - Theano 网络的打印输出

java - 如何(动态地)改变 Java 流的过滤条件?

java - 在 LinearLayout 中将左侧图像移至右侧

java - struts登录后如何重定向到上一页

debugging - 如何在 Pycharm 中本地调试 Google App Engine Web 应用程序?

c - 以文本格式打印数字的数字

azure - 如何调试 Azure 交换过程(有时会导致站点关闭)

java - 我想在电子邮件正文(不是附件)中嵌入 excel(xls/xlsx) 文件