调试事件时,我希望看到“完整”堆栈,特别是触发事件的实际事件或方法。
一个简单的例子是在表单上放置一个ComboBox,并编写一个onChange事件。 onChange事件将在用户更改comboBox时触发(显然),但也可以通过其他例程触发,例如,在启动时,formActivate将触发它。
如果我在comboBox的OnChange事件中放置断点,我将看不到触发堆栈。为什么会这样,如何在调试期间获得这个“其他”堆栈信息?
我知道我可以逐步完成活动,最终会让我回到触发代码,这不是我想要的。
谢谢!
我想我会张贴一张如何启用dcu的图片。请注意,FormCreate事件现在实际上出现在堆栈中。
这是两个不同堆栈轨迹的图像。断点在两者中完全相同,请注意在第二次启用调试dcu后,我从代码中获取堆栈信息(不仅仅是vcl / rtl)。
答案 0 :(得分:2)
我怀疑你错过了堆栈跟踪中的RTL / VCL函数。要使它们显示,请在项目选项中启用调试DCU 。
答案 1 :(得分:0)
启用Debug DCU后,我在堆栈中看到了自己的代码。 具体来说,FormCreate处理程序仅在启用调试后出现 的DCU。我很惊讶。
请参阅this:
基于帧的方法的堆栈帧
RTL和VCL单元在关闭“堆栈帧”选项的情况下编译。这意味着任何基于帧的方法都无法在RTL / VCL单元中找到短例程。
然而,这一事实也没有那么明显的后果。请考虑以下代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
TStringList.Create;
end;
此代码通过泄漏TStringList实例来创建简单的内存泄漏。跟踪工具将检测泄漏并为其构建调用堆栈。由于为您的项目启用了“堆栈帧”选项,Button1Click例程具有堆栈帧。可以预期基于帧的跟踪方法将发现对Button1Click的调用并将其添加到调用堆栈。
事实并非如此。
Button1Click的堆栈框架允许方法识别调用者(在本例中为:TControl.Click)。那是因为堆栈帧不包含有关例程本身的信息。它包含有关来电者的信息:返回地址。 Button1Click例程的返回地址将指向TControl.Click。
但是Button1Click怎么样?由于TStringList是来自RTL的类 - 它的编译没有“Stack Frames”选项。因此,构造函数没有堆栈帧(因为它是非常简单的代码,不需要堆栈帧)。因此,基于帧的跟踪方法无法识别Button1Click例程。