首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取/检查进程kernel32的内部win32状态(为TerminateThread的安全使用)

获取/检查进程kernel32的内部win32状态(为TerminateThread的安全使用)
EN

Stack Overflow用户
提问于 2020-04-20 15:39:09
回答 1查看 173关注 0票数 0

我已经为用户可用的线程编写了一个带有终止选项的线程池。正如Documentation of API terminateThread()中所描述的,

如果目标线程在终止时正在执行某些kernel32调用,则线程进程的kernel32状态可能不一致。

我可以亲自验证这个问题:在该条件下终止线程会导致内存分配问题(以及其他问题),但修复该条件同时解决了问题。

问题

因此,我想在每次使用

  1. 之后检查这个内部状态。如果terminateThread()在kernel32.dll中引起了进程内部状态的问题,我想引发一个异常--并在登录到用户之后终止进程(除非仍然可以修复内部状态)。

这可行吗?也许通过找到相关状态变量的地址(或者类似的东西-通过匹配kernel32的pdb文件或其他方式)?这种情况对我来说很糟糕--如果我不能解决它,我要么省略三池的终止选项,要么把线程留给自己。任何提示都会是appreciated!

  • Is,还有其他win32函数会导致类似的问题吗?

  • a。当它调用了一个绝对不会返回的阻塞kernel32函数时,为自己留下一个线程安全吗?

如果win32函数返回,而lambda函数已被销毁,会发生什么?

我为什么要问这个?(补充资料)

我在我的项目中有一个定制的线程池,在这里我调用了一些win32 API,这些API有时会永远阻塞。因此,我使用超时来调用它们。当到达超时时,我调用terminateThread()并让我的线程池返回“不成功的调用状态”。

有时,我的当前应用程序会陷入僵局。我发现这个死锁发生在线程池中,所以我正在寻找替代terminateThread()的方法(如我在问题中描述的那样离开线程),或者试图修复内部状态,或者至少验证terminateThread()是否是死锁的根源。

我也想在其他项目中重用这个线程池,所以我应该保证它的安全性。

更新:问题解决了。

我在我的应用程序中发现了这个bug :当我的线程池中的超时时间已经很低(大约200 ms)时,它实际上是对terminateThread()的调用。线程在没有阻塞时就被终止了(也就是说,如果超时时间更长,那么线程就会正常工作并返回)。从内核堆栈跟踪中,我发现在内核模式下,当线程终止时,一个互斥锁被锁定,而当线程退出时,其他线程已经在等待那个互斥体。

这个问题最初似乎是通过将最小超时增加到1000 ms来解决的,但我并不满意:我的解决方案是在到达超时时在堆上创建lambda,将lambda和线程留给自己而不终止,并将其添加到_ToTerminateThreads列表中。列表在10分钟内终止一次(等待10分钟,复制列表,等待另一分钟,然后终止线程并删除lambdas)。

尽管如此,经过测试和几个小时的调试,我还是会有堆损坏。最后,我发现了以下内容:我留给删除的线程写入了用户函数使用的内存(传递给了线程池)--它们被释放了,因为线程池已经返回。这导致了最终的问题,所以最后的解决办法是将超时时间增加到一个安全的数量。

我建议所有需要这样一个特性的人将其部署到子进程,并终止该进程,而不是使用线程。

我保留这个问题,因为主要的四个问题还没有回答。对于我的问题,我不再需要他们的答案,但他们可能是有趣的其他成员的堆栈溢出。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-27 03:09:14

我的问题解决了,尽管这与三个问题无关。我试着用相反的顺序回答:

(

  • ad 3.b.)如果一个外部函数返回,并且您的本地lambda已被删除,则cpu将不知道这一点,并尝试将该偏移量处的字节作为CPU指令处理。that!
  • ad 3.a.)是的,如果你100%确定外部函数永远不会返回,就可以安全离开(否则,当返回

时,它会破坏你的应用程序。)

代码语言:javascript
复制
1. if you deleted the rest of the code with the same way explained in **b.**
2. if you haven't deleted the lambda or it's a gobal function, it'll run the rest of function which may be editing dynamic allocated memories (heap, not stack) which has been deallocated and cause heap corruption or simply just edit some global variables).

  • ad 2.)我搜索了危险的winapi函数,除了TerminateThread()没有找到任何结果。如果您知道其中一个,请添加注释或编写另一个answer.
  • ad 1.) --我没有任何解决方案来检查/修复Microsoft引用的进程的内部kernel32状态。我认为微软的一个读过kernel32.dll源代码的人应该回答这个问题。

除了这种kernel32状态之外,TerminateThread()还会引起许多其他问题(如资源/堆分配、互斥锁、泄漏等等),因此,除非您100%确定您正在做什么,否则永远不要使用它。

阅读评论中链接的@RichardCritten文章:TerminateThread()

我代码中的错误是什么?

我用低超时(300 ms)打电话给TerminateThread()。当一台机器资源低时,该功能仍在运行(我指的是非阻塞调用!)我终止了这个函数,从而导致了一个内核互斥锁。这个锁定的互斥锁让所有其他线程等待--而不是在它们返回时退出。

备注

当我没有得到任何答案后,我从我发现的东西中回答了我自己的问题。因此,它可能包含一些错误的信息。如果有什么不对劲的地方,请纠正我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61326365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档