Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 正在寻找调试棘手的windows服务启动程序gremlin的想法_C++_Multithreading_Debugging_Windbg - Fatal编程技术网

C++ 正在寻找调试棘手的windows服务启动程序gremlin的想法

C++ 正在寻找调试棘手的windows服务启动程序gremlin的想法,c++,multithreading,debugging,windbg,C++,Multithreading,Debugging,Windbg,在过去的几个月里,我从QA那里收到了一些关于我们的一项服务挂起的报告。在使用WinDbg检查挂起转储时,每次我都会发现相同的事情:加载程序锁关键部分被锁定,但所属线程却无处可寻。由于线程已经消失,我能看到的唯一跟踪是它留下的全局关键部分,我看不到线程上运行的代码,甚至看不到线程来自哪个DLL,它甚至可能不是我们的(即第三方供应商) 这个问题是非常零星的,在过去的6个月里可能只在野外自然出现了3-4次。所有其他时间,服务都能完美运行。所以这让我相信这是某种时间/比赛条件的事情 最近,我决定自己解决

在过去的几个月里,我从QA那里收到了一些关于我们的一项服务挂起的报告。在使用WinDbg检查挂起转储时,每次我都会发现相同的事情:加载程序锁关键部分被锁定,但所属线程却无处可寻。由于线程已经消失,我能看到的唯一跟踪是它留下的全局关键部分,我看不到线程上运行的代码,甚至看不到线程来自哪个DLL,它甚至可能不是我们的(即第三方供应商)

这个问题是非常零星的,在过去的6个月里可能只在野外自然出现了3-4次。所有其他时间,服务都能完美运行。所以这让我相信这是某种时间/比赛条件的事情

最近,我决定自己解决这个问题。我使用WinTask脚本设置了一台机器,该脚本不断启动/停止所述服务。好消息是我可以在5-6小时内重现这个问题

现在进入下一部分:如何隔离它

这就是我迄今为止所尝试的:

  • 使用gflags映像设置中的“调试器”字段,在cdb下自动运行服务。到目前为止,它已经运行了两天,而且从未挂起,所以我认为调试器引入了足够的时间更改,使问题不可见

  • 下载了应用程序验证程序,并将进程配置为使用该验证程序运行。发现了一个完全不相关的错误,我们创建了CComBSTR临时变量,将其分配给一个变量,并将该变量传递到函数调用中,即使CComBSTR在该点之前长时间删除了分配的字符串。不要相信这个bug是相关的,因为字符串是只读的,并且它运行的线程不是正在消亡的线程

  • 我写这篇文章是为了防止你们想到我没有考虑的事情

    我认为有一个windows实用程序可以人为地在CPU上加载,并做其他事情来弹出竞争条件,我认为应用程序验证器做了这样的事情,但显然没有。有人知道我在说什么吗,还是我只是在胡思乱想


    除非周末有什么事情发生,否则我的下一步就是禁用所有调试器,返回stock并破解其中一个DllMains来记录THREAD_ATTACH/THREAD_DETACH事件。至少我能够截获创建时正在消亡的线程。这可能会有一些启发。

    我可能会尝试附加一个内核调试器,然后在应用验证程序下运行该进程。AV检查在保存CS时卸载DLL,并终止仍保存CS的线程。因此,这些断点应该在内核调试器中触发,然后希望您可以在act中捕获它。希望在KD下运行它不会像用户模式调试器那样减慢速度。

    一些随机想法:如果附加调试器没有帮助,那么下一步就是插入(最后一点)。但是,一个线程怎么能在不破坏整个过程的情况下就死掉呢?你在什么地方发现了异常吗?您可能也想在那里登录。如果有帮助的话,您还可以将WinDbg设置为在所有第一次机会异常时中断。WinDbg输出窗口无论如何都会显示第一次机会异常,即使您没有中断。

    我会尝试一个非侵入性调试器,看看如何进行,虽然您无法停止进程,但您应该能够看到任何调试消息以及任何启动和停止的线程,它应该对流程性能的影响最小。我通常使用windbg进行调试,但我认为cbd也有类似的选项。这很可能会让你看到过程中发生了什么,并且至少开始帮助你缩小范围。您可能需要确保做的一件事是重定向输出(.windbg中的logopen),以确保没有任何内容超出缓冲区

    结果证明我比我意识到的更接近解决方案。由于服务在cdb下运行,它改变了时间,然后使用应用程序验证程序运行它,这进一步改变了时间(启用页面堆会降低分配速度),所以我缺少的秘密成分是prime95.exe。以高于正常优先级运行prime95.exe,真的搞砸了我试图不改变的任何时间,但它使问题在15分钟内出现

    原因是:

    用于从硬件板获取数据的第三方SDK。当我们的服务启动时,我们将查询不同的捕获组件的功能。查询完成后,我们释放组件实例。显然,这一个DLL启动了一个单独的线程,该线程获得了加载程序锁,然后在该线程中进行了一系列初始化。如果在这段时间内,我们完成了功能查询,并且我们释放了组件,那么他们的代码将在另一个线程上调用TerminateThread(),从而永久锁定加载程序锁。Prime95减慢了速度,足以让我捕捉到这种比赛状态,并获得以下验证器停止消息:

    =======================================
    VERIFIER STOP 00000200: pid 0x1A8C: Thread cannot own a critical section. 
    
    0000091C : Thread ID.
    77E17340 : Critical section address.
    00000000 : Critical section debug information address.
    00000000 : Critical section initialization stack trace.
    
    有趣的是,这个线程正在“消失”,没有任何例外,所以调试器甚至不会抓住任何第一个机会。谁使用TerminateThread


    谢谢大家的建议和支持。事实上,我开始期待午餐时开车去Radioshack买一条串行电缆,然后花几天时间和KD一起玩。看来要等到下次了:)

    -1??为什么?我没有展示足够的细节吗?看起来我没有做足够的研究吗?当人们被软件开发问题难倒时,他们不会问stackoverflow吗?是的,这是一个完全正确的问题。唯一能让它变得更好的是发布一些代码。我想这就是为什么有人被否决了。这是一款已经上市10多年的生产应用程序。我甚至不知道是什么引起的