【问题标题】:If test pass when it should not如果测试在不应该的时候通过
【发布时间】:2012-03-12 16:01:59
【问题描述】:

看起来我有一个 JIT 错误(另一个:/):

我有这段代码:

    private Boolean m_bIsLoaded = false;

    public Boolean IsLoaded
    {
        get { return this.m_bIsLoaded; }
        set { this.m_bIsLoaded = value; }
    }

    public long DocGedCourrier {
        get {
            if ((this.IsLoaded == false)) {
                this.Load();
            }
            return this.GetInt64Value("ID_DOCGEDCOURRIER");
        }
        set {
            this.SetValue("ID_DOCGEDCOURRIER", value);
            NotifyPropertyChanged("DocGedCourrier");
        }
    }

我正在调试的 x64 平台(Windows XP Service Pack 3)上运行 Windows 服务,没有进行优化。

当我远程连接调试器并在 this.Load() 方法上放置断点时,调试器停止。如果我查看 this.IsLoaded 的值,它会返回 True。

如果我在未附加调试器的情况下运行服务,则始终调用 Load() 函数,即使 IsLoaded == True。

如果我在附加调试器的情况下运行服务,则在我逐步调试时不会调用 Load()。

如果我在 x86 平台(Windows XP Service Pack 3)上运行该服务,无论是否连接调试器,它都能完美运行。

m_bIsLoaded 无法更改,因为 m_bIsLoaded 仅使用 IsLoaded 属性和 set { this.m_bIsLoaded = value; 设置。 } 只调用一次,IsLoaded = true。

我 99.99% 确定这是 JIT 错误,因为我已经遇到过这种问题(另请参阅 Variable is not incrementing in C# Release x64)。

我的问题是:

我怎样才能发现这种问题并绝对避免它们?

谢谢,

编辑

我添加了一个锁以确保 IsLoaded 不会被另一个线程修改:

    public readonly Object Lock = new Object();

    public virtual Object Load()
    {
        lock (Lock)
        {
            if ((IsLoaded))
            {
                return this;
            }
        }
               ...
    }

    public Boolean IsLoaded
    {
        get { return this.m_bIsLoaded; }
        set
        {
            lock (Lock)
            {
                this.m_bIsLoaded = value;
            }
        }
    }

它没有解决问题。正如您在此屏幕截图中看到的那样:http://img15.hostingpics.net/pics/125986Screenshoot.jpg。返回 this is not call 即使 IsLoaded 设置为 True。

我排除了多线程访问的可能性。顺便说一句,IsLoaded 仅在字段初始化时设置为 false。如果 IsLoaded 为 True,我的代码中就不可能再有 False 值。

我能做些什么来防止这种情况发生?

【问题讨论】:

  • 尝试在 IsLoaded 属性的 set 部分设置断点。当调试器停止时,查看您的堆栈窗口以找出谁在调用该属性
  • 正如我所提到的,该集合只被调用一次。我使用断点检查了这一点。分配的值为 True。之后,如果通过,即使 IsLoaded 返回 True。
  • 您确定这不是可见性问题,即 m_BIsLoaded 字段是否仅由同一线程访问/修改?
  • False 永远不会分配给 m_bIsLoaded 或 IsLoaded。唯一的错误分配是在 m_bIsLoaded 的声明中。
  • @Filimindji,确保二进制文件是正确的(只是为了偏执——你将它作为服务运行,所以二进制文件可能是旧的)。向构造函数和 Load 方法添加跟踪语句,记录完整的调用堆栈并确保跟踪输出到文件 - 可能会显示一些有用的东西。

标签: c# 64-bit jit


【解决方案1】:

这可能是由某种竞争条件引起的。你的IsLoaded 的setter 和DocGedCourrier 的getter 是否在一个线程中运行?

【讨论】:

    【解决方案2】:

    该死.. IsLoaded 最初设置为 False,但在调试器中查看另一个属性的值导致 IsLoaded 传递给 True。

    不管是什么原因,谢谢你的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      相关资源
      最近更新 更多