【问题标题】:Dump Critical Section Queue (Threads waiting)转储关键部分队列(线程等待)
【发布时间】:2012-08-17 08:33:37
【问题描述】:

我有一个问题(崩溃转储),我的关键部分被破坏,但在检查 LockCount 后,我​​注意到有 1 个线程在等待它(似乎线程已被唤醒,但尚未进入,因为锁定状态未锁定)。

我想看看哪个线程被唤醒了。我知道关键部分有一个等待线程的队列,如果我可以转储这个队列/列表结构,我应该能够回答我的问题,有什么想法可以做吗?

【问题讨论】:

  • 您应该尝试获取所有线程的堆栈跟踪。也许这个页面会有所帮助? msdn.microsoft.com/en-us/library/dd554943.aspx
  • 不确定我是否理解 - 是什么在破坏 CS?
  • @MartinJames 抱歉不清楚。我的一个对象的析构函数正在删除关键部分(这没关系)。但是有一个线程已被唤醒以在其他地方获取 CS。由于线程刚刚被唤醒,未进入CS !cs -s 地址说明没有线程拥有该CS。

标签: c++ synchronization windbg critical-section


【解决方案1】:

CriticalSection 对象定义为

typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;

RTL_CRITICAL_SECTION 定义为

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

OwningThread 将包含拥有线程的句柄。 因此,您可能只需阅读CriticalSection 数据结构即可获取所属线程的句柄。

DWORD WINAPI GetThreadId(_In_ HANDLE OwningThread);

将返回所属线程的 ID。

但是,OwningThread 的定义存在一个小问题。 MSDN 报告该字段实际上包含线程 ID 本身。

你可以使用

GetThreadInformation(OwningThread,....);

获取更多线程详细信息。

MSDN 上的

Break Free of Code Deadlocks in Critical Sections Under Windows 在这种情况下是必读。特别是RTL_CRITICAL_SECTION_DEBUG 结构中的EntryCount/ContentionCount 字段可能会回答这里的问题。

【讨论】:

  • 这是我通常做的。但是,我为 OwningThread 获得了 null,但我的 LockCount 表明一个线程正在等待并且已被唤醒。我在想也许它还没有进入CS。
  • 我想知道是不是对LockCount有误解。请参阅 MSDN 上的 this
  • LockCount 的含义从 Sever 2003 起略有变化。我很确定我已经正确解释了它,我只是做了一些位操作来计算各个部分(即线程状态、线程唤醒和线程等待锁定)。
【解决方案2】:

你试过 !locks 吗?在此处的 WinDBG 文档中有关于查看进程中的关键部分的信息:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff541979(v=vs.85).aspx

【讨论】:

  • 是的,我有。问题是我知道 CS 的地址,而且我知道它还没有拥有线程。我认为线程已被唤醒但尚未进入 CS。我希望找出被唤醒的线程。
猜你喜欢
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-19
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多