War*_* P 4 delphi debugging design-time
我不确定如何追踪以下崩溃:
当卸载我公司内部使用的设计时包时会发生这种情况。这是我们的代码,因此这是我们要修复的错误,而不是第三方组件供应商的问题。
似乎涉及一个线程,但由于它发生在 Classes.pas 中的 Function ThreadProc 中,我猜测它是一个裸露的 System/RTL 线程,甚至没有我应该在代码中搜索的 TThread 类包装器。(问题A部分:是这样吗?)
调用堆栈不包含我的任何代码,只包含 IDE 本身,调用堆栈中的基本函数是 ntdll.RtlInitializeExceptionChain。
某些 TThread.Execute 方法中的访问冲突的调用堆栈示例,显示调试器没有提供有关涉及哪个线程的详细信息:
:7599b9bc KERNELBASE.RaiseException + 0x58
:516b4965 ; c:\program files (x86)\embarcadero\rad studio\8.0\bin\exceptiondiag150.bpl
:5003b058 NotifyNonDelphiException + $1C
:77be6a8b ; ntdll.dll
:77bb0143 ntdll.KiUserExceptionDispatcher + 0xf
rtl.Classes.ThreadProc($CB9ED70)
rtl.System.ThreadWrapper($403E910)
:75fb339a kernel32.BaseThreadInitThunk + 0x12
:77bd9ed2 ntdll.RtlInitializeExceptionChain + 0x63
:77bd9ea5 ntdll.RtlInitializeExceptionChain + 0x36
Run Code Online (Sandbox Code Playgroud)
当我尝试查看线程信息时,作为我的目标可执行文件的第二个 Delphi IDE 本身崩溃,但我能够继续在我的 Delphi 调试主机实例中查看信息。
我知道调试设计时包的技术,并且我正在使用所述技术。也就是说,我有一个 Delphi (BDS.exe) 的第一个副本,启动了第二个副本,因为包项目已在其运行参数中设置,在“主机应用程序”编辑框中设置了 Delphi XE 的主 bds.exe。( C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\bin\bds.exe
)。因此,当我在调试模式下运行我的包时,它会将自身加载到 Delphi IDE 中。
问题 B 部分是:设置断点的最佳位置是什么,以便我可以看到非 TThread 线程以及正在创建的基于 TThread 的线程?如果无法设置断点,那么是否可以采用其他方法来查找正在创建线程的代码?
更新:我发现在 Classes.pas 的 ThreadProc 函数中读取 Thread.Execute 的行中设置断点,可以在每次 TThread 启动时命中断点。这足以从初始化部分找到由设计时或运行时包启动的线程,但我希望存在一种甚至更低级别的方法来执行此操作。
War*_* P 5
我通过以下方式调试了设计时包崩溃:
如上所述,在主机应用程序中使用运行参数将 Delphi 设置为自行运行,路径为 c:\path-to-delphi-install\bin\bds.exe
.
在 System.pas 中的函数 ThreadProc 行中设置断点。
打开windows.pas,在第30,000-33,000行左右有这样一行:
function CreateThread; external kernel32 name 'CreateThread';
使用 F8 在上面的行上设置断点。现在,当正在调试的代码中的任何内容调用该 Win32 函数时,无论是否通过 TThread,您都会得到一个断点。