gpt4 book ai didi

multithreading - 如何找出 Delphi 程序中所有线程的创建者是谁?

转载 作者:行者123 更新时间:2023-12-03 14:42:51 25 4
gpt4 key购买 nike

如果您有一套干净的 Delphi 代码,并且所有线程都是使用 TThread 创建的,您可以在构造函数方法 (TThread.Create) 中设置断点并找出谁创建了您的线程。您甚至可以尝试使用 Delphi TThread 对象中内置的功能来命名所有线程,该功能允许您为每个线程设置调试名称。

但是,如何识别持久的、难以找到的额外线程,这些线程仍然是匿名的(没有调试名称),并且在应用程序启动时出现在模块初始化期间。我可以单步执行模块初始化,但我无法确定可能创建线程的所有源模块(尤其是已完成的 900 多个模块初始化部分),而且我还没有找到一种方法添加一条调试消息(使用断点属性和消息),该消息将在初始化时转储每个单元名称。创造性地使用 System.pas 中设置的断点和日志记录消息使我可以在调试简单的应用程序时做一些事情,但是我的应用程序变得越复杂,我就越感觉被线程蒙蔽了双眼,这两个线程都是在中间创建的应用程序运行时的应用程序,以及在模块初始化时创建的应用程序(即在您进入项目 dpr 中的第一行代码之前)。

我想知道您可能发现了哪些先进技术来识别和找出谁创建了特定线程。如果我们使用像 GDB 这样的调试器,而不是像 Delphi IDE 中内置的 delphi 调试器内核(Turbo Debugger?)这样的调试器,我认为我们可以在像 BeginThread 本身这样的 Windows api 函数上设置断点。但我认为我无法在 Delphi 中做到这一点。

更新:我不知道您可以在 windows.pas 的实现部分为外部 Windows DLL(如 kernel32.dll)设置断点。

更新2:看来David H的答案是通用的最佳想法。我还在研究我现在正在编写的一个小帮助程序代码库,它维护以前见过的线程 ID 字典,并根据创建时间(什么函数)将一些调试名称分配给其他未命名的线程我们在注意到新线程存在之前就调用了)。我认为这将帮助我缩小 40 多个编号线程的范围,以便它们都得到命名,即使其中一些是在外部 C/C++ dll 中或由 COM 进程创建的。

最佳答案

我可能会考虑使用类似 Process Explorer 的工具和 madExcept ,但是有很多工具可以提供帮助。

我不相信 Delphi 使用 Turbo Debugger。更重要的是,Delphi 完全能够在像 CreateThread 这样的 kernel32 入口点上设置断点。

我将在启用调试 DCU 的情况下运行,并在 Windows.pas 中的 CreateThread 实现上设置断点。中断后,切换到 CPU 窗口并进入例程。您将看到 JMP DWORD PTR [address] 指令。跳过这个,嘿,你现在正在 kernel32 中进行调试。您可以在此处设置断点。

现在,如果您重置应用程序并再次开始调试,您将中断源自您进程的所有对 kernel32.CreateThread 的调用。检查调用堆栈将告诉您如何到达那里。它看起来像这样:

enter image description here

最后,我不确定为什么您对应用程序创建线程感到困扰。大多数大小合适的应用程序都会创建大量线程 - 这样做是完全正常的。您遇到什么问题?

关于multithreading - 如何找出 Delphi 程序中所有线程的创建者是谁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4855638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com