【发布时间】:2012-01-15 06:15:02
【问题描述】:
在过去的几个月里,我很少收到来自 QA 的关于我们的一项服务挂起的报告。在使用 WinDbg 检查挂起转储时,每次我都发现同样的事情:加载程序锁临界区被锁定,但找不到拥有线程。由于线程消失了,我能看到的唯一痕迹是它留下的全局临界区,我看不到线程线程上运行的代码,甚至看不到该线程来自哪个 DLL,它甚至可能不是其中之一我们的(即第三方供应商)。
此问题非常零星,在过去 6 个月中仅在野外自然发生过 3-4 次。在所有其他时间,服务运行完美。所以这让我相信这是某种时间/竞赛条件。
最近,我决定自己解决这个问题。我使用 WinTask 脚本设置了一台机器,该脚本不断启动/停止所述服务。好消息是我可以在 5-6 小时内重现问题。
现在进入下一部分:如何隔离它?
这是我迄今为止尝试过的:
使用 gflags 映像设置中的“调试器”字段在 cdb 启动时自动运行该服务。到目前为止,这已经运行了两天并且从未挂起,所以我认为调试器引入了足够的时间更改以使问题不可见。
已下载应用程序验证程序并将进程配置为使用它运行。发现了一个完全不相关的错误,我们在其中创建 CComBSTR 临时变量,将其分配给 VARIANT 并将变量传递给函数调用,即使 CComBSTR 到那时已长时间删除了分配的字符串。不要相信这个错误是相关的,因为字符串是只读的,并且它运行的线程不是正在死亡的线程。
我写这篇文章是为了让你们想到我没有考虑的事情。
我虽然有一个 Windows 实用程序人为地在 CPU 上施加负载并做了其他事情来使竞争条件弹出,我认为应用程序验证器做了这样的事情,但显然它没有。有谁知道我在做什么,还是我只是在做梦?
除非周末发生什么事情,否则我的下一步是禁用所有调试器,返回库存并破解一个 DllMains 以记录 THREAD_ATTACH/THREAD_DETACH 事件。至少我将能够拦截创建时即将死去的线程。这可能会有所启发。
【问题讨论】:
-
-1??为什么??我没有显示足够的细节吗?看起来我没有做足够的研究吗?当人们被软件开发问题难住时,他们不会问 stackoverflow 吗?
-
是的,这是一个非常有效的问题。唯一能让它变得更好的是发布一些代码。我想这就是为什么有人开车过来投反对票的原因。
-
这是一款已经上市 10 多年的生产应用程序。我什至不知道是什么 DLL 导致了这个问题,更不用说在网上发布闭源公司代码了,即使我可以复制/粘贴 5M 行源代码。不知道发生了什么变化,但大约 6 个月前我第一次看到这个问题。
-
不要太担心投票者。我的印象是,有些人会否决/尝试关闭他们不知道答案的任何问题...祝您搜索顺利,希望有人会提供一些提示,尽管问题广泛 :)
标签: c++ multithreading debugging windbg