锁定损坏?魔术僵局?

 用户r5oydafsky 发布于 2023-02-13 12:02

我使用multethreading bug.现在我看到由于某种原因锁定甚至一次都没有执行但是被锁定了.我有下一堂课:

public sealed class Foo
{
       private readonly object _lock = new object();
       private static ulong _inCnt = 0;

    public void SomeMethod(ulong poo)
    {
        lock (_lock)
        {
           _inCnt++;
           ... [some code]
        }
    }
 }

我暂停了VS中的所有线程,检查了所有线程,看到只有一个线程SomeMethod,它正在等待lock (_lock)被释放(_inCnt = 0).我恢复线程,等待一段时间,暂停线程并看到相同的图片,同样(并且只有一个)线程仍在等待lock (_lock)进入SomeMethod并且_inCnt为零!但是如果锁定将会是一个或多个(_inCnt++lock (_lock)没有异常发生之后是第一行,我们不会中止线程).如何将其锁定为零并锁定?

1 个回答
  • 如果您的所有假设都是正确的,并且您确实没有意外的线程中止,那么您必须考虑GC堆数据损坏.System.Object中存储锁状态的字段相当容易受到攻击,它是对象中的第一个字段.因此,即使是在pinvoked本机代码中的适度缓冲区溢出也可能会覆盖该字段并使CLR认为锁定被保留.

    然而,假设是不可饶恕的问题和无法回答的问题的母亲.最好检查它们,它实际上是可调试的.我假设32位代码执行.使用Debug + QuickWatch并键入&_lock.这为您提供了对象引用的地址.切换到Debug + Windows + Memory + Memory1并输入您获得的地址.右键单击窗口并选择"4字节整数".您现在将看到对象的地址,它存储在GC堆中.从该数字中减去4并在"地址"框中键入结果.您现在可以看到存储锁定状态的字段.如果未保持锁定为0,如果保持锁定,则它包含拥有锁定的线程的Thread.ManagedId.您可以将它与Debug + Windows + Threads窗口相关联.

    三个基本场景:

    如果您在Threads窗口中找到该线程,那么您将遇到死锁,您将对该线程正在做什么非常感兴趣.双击它并查看"调用堆栈"窗口以查看它没有取得进展的原因

    如果你找不到该线程那么你有一个非常强烈的提示,你的代码遭受了"意外线程中止"的不幸事故

    如果您看到一个奇怪的随机数,那么您就会遇到GC堆损坏情况.

    2023-02-13 12:03 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有