JCLDebug堆栈跟踪缺少导致错误的实际代码行

时间:2011-05-12 03:13:26

标签: delphi

我正在使用JCLDebug(Click Here获取更多信息)在DUnit中显示堆栈跟踪。请参阅下面的堆栈跟踪。

堆栈跟踪显示所有调用函数的调用,该函数调用导致错误的实际函数。 ConvertScriptTestU的第238行调用另一个名为“GetDataLine”的函数(它在堆栈跟踪中丢失)然后调用IntToStr(它引发EConvertError)。为什么堆栈跟踪不包含 GetDataLine

这个堆栈跟踪没那么有用,因为我仍然需要解决GetDataLine中哪一行导致EConvertError。

我在这里使用DUnit,但是我在DUnit之外使用JclDebug时发现了同样的事情。

[答案]

只需将此行添加到项目文件中:

JCLdebug.JclStackTrackingOptions:=[stStack, stRawMode];

打开“原始模式”。您可能还需要调整一些编译器选项(例如'生成堆栈帧')

[/ THE ANSWER]

TestConversion: EConvertError
at SysUtils:0 SysUtils.ConvertErrorFmt$00414A7E
'''' is not a valid integer value
StackTrace
[00414A79]{ConvertDataTests.exe} SysUtils.ConvertErrorFmt
[007E2699]{ConvertDataTests.exe} ConvertScriptTestU.ConvertDataTest.WriteDataToFile (Line 238, "ConvertDataTestU.pas")
[007E2198]{ConvertDataTests.exe} ConvertScriptTestU.ConvertDataTest.TestConversion (Line 164, "ConvertDataTestU.pas")
[0053C66E]{ConvertDataTests.exe} TestFramework.TTestCase.RunTest (Line 2380, "TestFrameWork.pas")
[00537DBA]{ConvertDataTests.exe} TestFramework.TTestResult.RunTestRun (Line 1199, "TestFrameWork.pas")
[00538078]{ConvertDataTests.exe} TestFramework.TTestResult.Run (Line 1275, "TestFrameWork.pas")
[0053963A]{ConvertDataTests.exe} TestFramework.TAbstractTest.RunWithFixture (Line 1723, "TestFrameWork.pas")
[0053C4DD]{ConvertDataTests.exe} TestFramework.TTestCase.RunWithFixture (Line 2363, "TestFrameWork.pas")

3 个答案:

答案 0 :(得分:7)

这可能取决于您编译应用程序的方式。出于调试目的,您应该在编译器代码生成选项中将Stack Frames设置为On,并确保重新编译所有需要的单元,并且它们的符号可用。否则,编译器可能会选择不为某些函数生成它们。手动编码的纯汇编程序函数无论如何都可能没有堆栈帧,IIRC。如果在支持该功能的Delphi版本中内联函数,则可能会出现另一个问题。另外,您在JCL调试中设置了哪种堆栈跟踪? IIRC它支持两种方法,标准和“原始”。

答案 1 :(得分:2)

当出现错误时,会发生这种事情。由于没有用于执行堆栈跟踪的官方API,因此跟踪生成器必须在堆栈中向后移动,一次一帧。但是,如果任何介入函数没有设置堆栈帧,或者由于某种原因它以奇怪的方式执行堆栈操作,那么它可以抛出跟踪器。

这在64位Delphi中可能会更加可靠,因为Windows要求某种类型的堆栈帧,以便 it 可以在异常升级时正确展开堆栈,但对于32这是我们必须忍受的东西。

答案 2 :(得分:0)

参数可以放在寄存器EAX,EDX和ECX中的过程或函数在使用Delphi的默认register调用约定时不使用堆栈帧。

如果您使用stdcallcdecl调用约定,则调用该例程将始终使用堆栈。
如果设置stack frame on {$W+}{$STACKFRAMES ON} Delphi将始终生成堆栈帧,即使它们不需要也是如此。

我建议您在条件定义

中设置此编译器开关
{$IFDEF DEBUG}
   {$W+}
{$ELSE}
   {$W-}
{$ENDIF}

请参阅:http://docwiki.embarcadero.com/RADStudio/XE/en/Stack_frames_(Delphi