使用 Windbg 进行关键部分挂起分析

2024-04-24

最近,当我的应用程序一段时间没有响应时,我通过 procdump 生成了一个转储文件。

当我在转储文件上运行 !locks 时,我得到一个单独的条目,如下所示:

0:000> !locks

CritSec +123456 at 00123456
WaiterWoken       No
LockCount         0
RecursionCount    2
OwningThread      aaaa
EntryCount        0
ContentionCount   0
*** Locked

只是那一份清单。就这样。当我进一步深入时:

0:000> dt RTL_CRITICAL_SECTION 00123456
MyModule!RTL_CRITICAL_SECTION
  +0x000 DebugInfo      : 0x00aabbcc _RTL_CRITICAL_SECTION_DEBUG
  +0x004 LockCount      : 0n-2
  +0x008 RecursionCount : 0n2
  +0x00c OwningThread   : 0x0000aaaa Void
  +0x010 LockSemaphore  : (null)
  +0x014 SpinCount      : 0

问题:

1)我应该采取MyModule!RTL_CRITICAL_SECTION作为明确的线索,这个关键部分可能是在 MyModule 中定义的?

2)有没有办法让Windbg显示这个临界区的实际变量名? (即假设 #1 为真,并且这是应用程序代码已定义/访问的 CS。)

3) 为什么上述列表中的 LockCount 值彼此不一致? (一个为 0,另一个为 -2。)

4)我想我对LockCount的理解足够好,知道它不能低于-1。更不用说 RecursionCount 似乎与 LockCount 严重不一致。

我想最根本的问题是我应该将其归因于损坏的 CS 吗?


我可以使用示例应用程序轻松重现负 LockCount 的影响,以下是我的答案:

对您的问题的答复

关于1)

我应该以 MyModule!RTL_CRITICAL_SECTION 作为明确的线索,这个关键部分可能是在 MyModule 中定义的吗?

是的,这是您对关键部分的定义,它可能与 Microsoft 的定义相对应,也可能不相对应。要使用 Microsoft 的定义,请使用dt nt!_RTL_CRITICAL_SECTION

关于2)

有没有办法让Windbg显示这个临界区的实际变量名? (即假设 #1 为真,并且这是应用程序代码已定义/访问的 CS。)

是的,如果它被调用堆栈上的函数使用。和.frame,导航到框架,然后使用?? variableName显示变量,例如

0:000> k L2
 # ChildEBP RetAddr  
00 0116faa4 00d67419 KERNELBASE!DebugBreak+0x2
01 0116fc5c 00d67ebe CriticalSectionLeaveTwice!main+0x109
0:000> .frame 1
01 0116fc5c 00d67ebe CriticalSectionLeaveTwice!main+0x109 [c:\users\t\documents\visual studio 2015\projects\criticalsectionleavetwice\criticalsectionleavetwice\criticalsectionleavetwice.cpp @ 24]
0:000> ?? CriticalSection
struct _RTL_CRITICAL_SECTION
   +0x000 DebugInfo        : 0xffffffff _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : 0n-2
   +0x008 RecursionCount   : 0n2
   +0x00c OwningThread     : 0x00000d6c Void
   +0x010 LockSemaphore    : (null) 
   +0x014 SpinCount        : 0x20007d0

关于3)

为什么上述列表中的 LockCount 值彼此不一致? (一个为 0,另一个为 -2。)

LockCount不再是真正的锁定计数,如中所述这个答案 https://stackoverflow.com/a/7408797/480982。相关部分:

在 Microsoft Windows Server 2003 Service Pack 1 及更高版本的 Windows 中,LockCount 字段的解析方式如下:

  • 最低位显示锁定状态。如果该位为0,则临界区被锁定;如果为1,则临界区未被锁定。
  • 下一位显示是否已为此锁唤醒线程。如果该位为0,则表示已经有一个线程被该锁唤醒;如果为1,则没有线程被唤醒。
  • 其余位是等待锁的线程数的反码。

恕我直言!locks命令应该为你做解释。

的特殊价值-2 is 11111111 ... 1111110二进制,所以最后一位是0,意味着临界区被锁定。前面的位是1,所以没有线程被唤醒。余数的反码为0,对应锁计数输出!locks.

这意味着您分析的关键部分不涉及死锁。

关于4)

我想我对 LockCount 有足够的了解,知道它不能低于 -1。更不用说 RecursionCount 似乎与 LockCount 严重不一致。

See #3.

关于未编号的问题5)

我应该把这归因于损坏的CS吗?

不,它似乎没有被损坏。

使用!dlk进行死锁分析

要检查它是否导致死锁,我建议使用sosex /questions/tagged/sosex's (download http://www.stevestechspot.com/default.aspx) !dlk命令。虽然它主要是 .NET 的扩展,但我曾经请求即使没有 .NET 也能使其适用于关键部分 - 并且该功能是在 SOSex 的较新版本之一中实现的。

如果找不到 .NET,它将输出有关该事实的警告,然后继续分析关键部分:

在你的情况下,它可能看起来像这样:

0:000> !dlk
Unable to initialize .NET data interface. The CLR has not yet been loaded in the process (mscorwks/clr module not loaded).
Examining CriticalSections...
No deadlocks detected.

Usage:

.load c:\path\to\sosex.dll
!dlk

如果它识别出死锁,则非常容易阅读。如果没有,您仍然需要应用其他技术,即不能保证不存在其他类型的死锁(例如,如果等待链包含其他类型的同步对象,如线程、事件等)。

示例输出(不适用于关键部分,但类似):

0:010> !dlk
Deadlock detected:
CLR thread 4 holds sync block 00000000024c6970 OBJ:000000007fff0f80[System.String] STRVAL=SYNC1
             waits sync block 00000000024c6928 OBJ:000000007fff0fa8[System.String] STRVAL=SYNC2
CLR thread 5 holds sync block 00000000024c6928 OBJ:000000007fff0fa8[System.String] STRVAL=SYNC2
             waits sync block 00000000024c6970 OBJ:000000007fff0f80[System.String] STRVAL=SYNC1
CLR Thread 4 is waiting at ConsoleTestApp.ConsoleTestApp.MonitorDeadlockThreadProc()+0xa4(IL) [C:\dev\ConsoleTestApp\ConsoleTestApp.cs, line 195]
CLR Thread 5 is waiting at ConsoleTestApp.ConsoleTestApp.MonitorDeadlockThreadProc()+0xa4(IL) [C:\dev\ConsoleTestApp\ConsoleTestApp.cs, line 195]

1 deadlock detected. 

挂分析

!analyze -hang and 调试诊断 https://www.microsoft.com/en-us/download/details.aspx?id=49924可能有助于挂起分析。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Windbg 进行关键部分挂起分析 的相关文章

  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • 为什么大多数平台上没有“aligned_realloc”?

    MSVC有自己的非标准函数 aligned malloc aligned realloc and aligned free C 17和C11引入了 std aligned alloc 其结果可以是de分配有free or realloc B
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • 从 C 结构生成 C# 结构

    我有几十个 C 结构 我需要在 C 中使用它们 典型的 C 结构如下所示 typedef struct UM EVENT ULONG32 Id ULONG32 Orgin ULONG32 OperationType ULONG32 Size
  • SFINAE 如何使用省略号?

    过去 当使用 SFINAE 选择构造函数重载时 我通常使用以下内容 template
  • 获取尚未实例化的类的函数句柄

    我对 C 相当陌生 我想做的事情可能看起来很复杂 首先 我想获取一些函数的句柄以便稍后执行它们 我知道我可以通过以下方式实现这一目标 List
  • 如何生成 appsettings..json 文件?

    我有一个 ASP NET Core 2 WebAPI 它将部署在以下环境中 INT QA STAGE 生产环境 基于上述 我需要有appsettings
  • 从成员函数指针类型生成函子

    我正在尝试简化 通过make fn 预处理参数的函子的生成 通过wrap 对于 arity 的成员函数n 生成函子基本上可以工作 但到目前为止只能通过显式指定成员函数的参数类型来实现 现在我想从它处理的成员函数类型生成正确的函子 struc
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • 使用 HTMLAgilityPack 从节点的子节点中选择所有

    我有以下代码用于获取 html 页面 将网址设置为绝对 然后将链接设置为 rel nofollow 并在新窗口 选项卡中打开 我的问题是关于将属性添加到 a s string url http www mysite com string s
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L

随机推荐

  • Java应用程序cpu负载过高的解决办法

    今天 我发现我的服务器的cpu负载太高 并且服务器只运行一个Java应用程序 下面是我的操作步骤 I used top命令查找应用程序的 pid pid是25713 I used top H p 25713命令查找一些使用最多 cpu 的
  • 将 PNG 图像中的透明度替换为白色背景

    我有一个带有 Alpha 通道 即透明度 的 PNG 图像 我需要创建将图像层合成到白色背景上的版本 我想使用可编写脚本的命令 使用 CLI 工具 例如 Image Magick 将 PNG 直接无损地转换为 PNG 导致错误的非工作 Im
  • 命令行 Ruby 函数的手册页

    有没有办法从命令行获取 Ruby 函数的手册 像 funcR 中的手册页 The ri工具在这里可能会有所帮助 http rubylearning com satishtalim ruby ri tool html ri Array ri
  • 如何使用 CPANPLUS 自动捆绑包更新新版本的 Perl?

    我有 Perl 5 13 4 其中包含大量已安装的 CPAN 模块 我刚刚编译了 Perl 5 14 0 我想将 5 13 4 中的所有模块安装 重新编译 到 5 14 0 中 我可以 已经使用 cpanp 和 b 选项生成了已安装模块的捆
  • 在 R 中将矩阵组合成数组

    如果我创建了多个矩阵 如何将它们组合成一个数组 我有 8 个矩阵 每个矩阵有 200 行和 200 列 我需要将它们组合成一个 dim 200 200 8 的数组 所以我希望每个矩阵都是数组的一部分 您可以使用abind函数从abind包裹
  • 强制构建全局对象

    代码如下 struct S S debugbreak static const S g s 显然 我希望一些代码在启动时运行 这仅适用于某些具有外部代码引用的符号的源文件 对于静态库中没有任何从外部引用的符号的源文件 看起来编译器或链接器会
  • 如何声明带有值的 ArrayList? [复制]

    这个问题在这里已经有答案了 Java 中的 ArrayList 或 List 声明 https stackoverflow com questions 12321177 arraylist declaration java已提问并回答了如何
  • 是否可以在由同一父进程创建的两个子进程之间建立管道(LINUX,POSIX)

    我有多个孩子由同一个父母 分叉 我尝试构建pipe所有这些子进程之间的连接就像一个链表结构 孩子 1 向孩子 2 发送数据 孩子 2 向孩子 3 孩子 N 向孩子 1 发送数据 有没有正确的方法可以做到这一点 此外 如果我在进程之间创建和通
  • 为什么 JavaScript 的 parseInt 的基数默认为 8?

    在 JavaScript 的 parseInt 函数中将基数默认为 8 如果字符串以 0 开头 让我很烦恼 只是因为我仍然忘记将可选的第二个参数传递为 10 我正在寻找一个答案 告诉我为什么这样做有意义将其默认为 8 如果输入字符串以 0
  • 为什么预分配对列表有用?

    我知道预分配向量或矩阵很有用 因为它们始终存储在连续的内存块中 然而 就列表而言 它可以包含不同长度和模式的元素 所以我的第一个猜测是列表可能只包含指向其元素真实地址的指针 我对么 这里有一个相关问题列表的内部实现是怎样的 https st
  • Python 中的连续“is”运算符[重复]

    这个问题在这里已经有答案了 有人能为我解释一下吗 gt gt gt None is None is None True gt gt gt None is None is None False is 运算符不是接受 2 个操作数 从左侧比较对
  • 正则表达式在所有文件的函数调用中查找/替换参数模式

    我有一个很大的代码库 我们需要在特定函数的参数中进行模式更改 即函数的所有参数foo 从格式重命名something anotherThing将被重命名为something anotherThing 参数可以是任何内容 但始终采用 str1
  • 如何调试视频解码损坏?

    我刚刚开始为一家新公司工作 我的新角色要求我帮助调试他们通过解码帧接收到的视频损坏 尽管我打算深入研究代码并研究问题的具体细节 但它让我开始思考视频调试的总体情况 由于处理视频对我来说非常陌生 整个过程看起来相当复杂 而且似乎有很多地方可以
  • for 循环如何借用迭代器?

    一个人怎样才能拥有一个for in循环借用它正在操作的迭代器 例如 let x vec 1 2 3 4 let i x iter for a1 in i break iterate over just one i for a2 in i b
  • 如何替换 PathBuf 或 Path 的文件扩展名?

    我当前的解决方案是 let temp format png path file stem unwrap to string lossy path pop path push temp 这相当难看 需要至少 6 次函数调用并创建一个新字符串
  • AttributeError:“模块”对象没有属性“模型”

    谁能帮我解决这个问题 from django db import models Create your models here class Poll models model question models CharField max le
  • 同步框架服务器到服务器同步

    I have kind of a such scenario source microsoft com http i msdn microsoft com bb887608 Figure3 en us png Here i need to
  • 如何在 Python 3.8+ 和 Python 2.7 中使用 collections.abc

    在Python 3 3 抽象基类 中collections like MutableMapping or MutableSequence 被移至二级模块collections abc 所以在 Python 3 3 中 真实类型是collec
  • TypeScript:在对象上强制使用单个动态键

    有没有办法为具有以下属性的对象编写接口single动态命名的键 我能够编写一个接受任意数量的动态命名键的接口 但我想将其限制为只有一个 让我们从一些基础知识开始 然后逐步解决我的问题 在下面的接口中 对象只能有一个键 并且它被命名为 id
  • 使用 Windbg 进行关键部分挂起分析

    最近 当我的应用程序一段时间没有响应时 我通过 procdump 生成了一个转储文件 当我在转储文件上运行 locks 时 我得到一个单独的条目 如下所示 0 000 gt locks CritSec 123456 at 00123456