如何调试在Classes.pas中的ThreadProc中涉及崩溃的设计时包卸载崩溃? [英] How do I debug a designtime package unloading crash involving a crash in ThreadProc in Classes.pas?

查看:323
本文介绍了如何调试在Classes.pas中的ThreadProc中涉及崩溃的设计时包卸载崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何跟踪以下崩溃:


  1. 发生在卸载使用的Designtime包时在我公司内部。这是我们的代码,因此这是我们的错误修复,而不是第三方组件供应商的问题。


  2. 它认为一个线程涉及,但由于它发生在Classes.pas中的Function ThreadProc中,我猜这是一个裸机系统/ RTL线程,甚至没有TThread类包装器,我应该在我们的代码中搜索。 (问题A部分是这样吗?)


  3. 调用堆栈不包含我的代码,只有IDE本身,并且调用堆栈中的基本函数是ntdll.RtlInitializeExceptionChain。


在一些TThread.Execute方法中调用堆栈访问冲突的示例,显示调试器没有关于WHICH线程的细节:

 :7599b9bc KERNELBASE.RaiseException + 0x58 
:516b4965; c:\程序文件(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

当我尝试查看线程信息时,第二个Delphi IDE是我的目标可执行文件本身崩溃,但是我可以继续查看我的delphi调试主机实例中的信息。



我知道调试设计时间包的技术,我正在使用这些技术。也就是说,我有一个delphi(BDS.exe)的第一个副本启动了第二个副本,因为包项目已经在其运行参数中设置了主机应用程序编辑框中的主要bds.exe为Delphi XE。 ( C:\程序文件(x86)\Embarcadero\RAD Studio\8.0\bin\bds.exe )。因此,当我以调试模式运行我的包时,它将自己加载到Delphi IDE中。



问题部分B是:设置断点的最佳位置是什么,以便我可以看到非TThread线程,以及正在创建的基于TThread的线程?如果没有办法设置断点,那么如何找到代码创建线程的另一种方法呢?



更新:我发现在在Threades中,Thread.Execute在Classes.pas中的ThreadProc函数中获取每个TThread启动时的断点。这足以从初始化部分找到由设计时间或运行时包启动的线程,但我希望存在一个更低级别的方式来执行此操作。

解决方案

我以下列方式调试了设计时包裹崩溃:


  1. 如上所述,设置Delphi运行自身,使用运行参数,在主机应用程序中,路径为 c:\path-to-delphi-install\bin\bds.exe


  2. 在System.pas中功能ThreadProc的行中设置一个断点。


  3. p>打开windows.pas,并且在30,000-33,000行周围有一行如下:



    function CreateThread;外部kernel32名称CreateThread;


使用F8在上面的行上设置一个断点。现在,正在调试的代码中的任何东西调用Win32函数,无论是否通过TThread,都会得到一个断点。




I am not sure how to track down the following crash:

  1. It happens when Unloading a Designtime Package that is used in-house at my company. It is our code, thus it is our bug to fix, not a third party component vendor problem.

  2. It apppears that a thread is involved, but since it happens in the Function ThreadProc in Classes.pas, I'm guessing it's a bare System/RTL thread without even a TThread class wrapper that I should be searching for in our code. (Question Part A: Is that so?)

  3. The call stack contains none of my code, only the IDE itself, and the base function in the call stack is ntdll.RtlInitializeExceptionChain.

call stack example of an access violation in some TThread.Execute method that shows that the debugger gives no details on WHICH thread is involved:

 :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

When I try to view thread info, the second Delphi IDE that is my target executable, itself crashes, but I am able to continue to view information in my delphi debug host instance.

I am aware of techniques for debugging designtime packages, and I am using said techniques. That is, I have a first copy of delphi (BDS.exe) launching a second copy, because the package project, has set in its Run Parameters, in the Host Application edit box the main bds.exe for Delphi XE. (C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\bin\bds.exe). Thus when I run my package in debug mode, it loads itself into the Delphi IDE.

Question part B is: What is the best place to set a breakpoint so I can see non-TThread threads, as well as TThread-based threads being created? If there is no way to set a breakpoint, then how about an alternative means of finding what code is creating threads?

Update: I have found that setting a breakpoint in the line that reads Thread.Execute, in function ThreadProc, in Classes.pas, gets me a breakpoint hit on each TThread startup. That is enough to find threads started by a designtime or runtime package from its initialization section, but I'm hoping there exists an even lower level way to do this.

解决方案

I debugged the designtime package crash in the following manner:

  1. As already noted above, set up Delphi to run itself, using Run Parameters, in the Host Application, the path is c:\path-to-delphi-install\bin\bds.exe.

  2. Set a breakpoint in the line in function ThreadProc in System.pas.

  3. Open windows.pas, and around line 30,000-33,000 there is a line like this:

    function CreateThread; external kernel32 name 'CreateThread';

Set a breakpoint on the line above with F8. Now when anything in the code being debugged invokes that Win32 function, whether via TThread or not, you'll get a breakpoint.

这篇关于如何调试在Classes.pas中的ThreadProc中涉及崩溃的设计时包卸载崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆