delphi 2009,弹出菜单导致EStackOverFlow

时间:2011-04-10 14:12:30

标签: delphi exception delphi-2009 stack-overflow

筹码的一小部分

:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:0043797f TFont.SetData + $2F
:00437d92 TFont.SetStyle + $36
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:004378c5 TFont.Assign + $61
:004bf1f0 TThemedMenuItem.CalcBounds + $68
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:0043797f TFont.SetData + $2F
:00437d92 TFont.SetStyle + $36
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:004378c5 TFont.Assign + $61
:004bf1f0 TThemedMenuItem.CalcBounds + $68
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:0043797f TFont.SetData + $2F
:00437d92 TFont.SetStyle + $36
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:004378c5 TFont.Assign + $61
:004bf1f0 TThemedMenuItem.CalcBounds + $68
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:0043797f TFont.SetData + $2F
:00437d92 TFont.SetStyle + $36
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:004378c5 TFont.Assign + $61
:004bf1f0 TThemedMenuItem.CalcBounds + $68
:004b9839 TCustomActionControl.CMFontChanged + $1D
:0047fe17 TControl.Perform + $27
:0047eb54 TControl.FontChanged + $40
:0043797f TFont.SetData + $2F
:00437d92 TFont.SetStyle + $36
:004bb1d7 TCustomActionControl.CMTextChanged + $1F
:004801f1 TControl.WndProc + $2D5
:0047fe17 TControl.Perform + $27
:0047ded6 TControl.SetTextBuf + $22
:004ba9df TCustomActionControl.SetActionClient + $C7
:004b6aa7 TCustomActionBar.CreateControl + $D3
:004a8b6f TCustomActionMenuBar.CreateControl + $B
:004bdbee TCustomActionDockBar.CreateControls + $A
:00481779 TControl.WMContextMenu + $121

它继续......

我生成的最后一个代码执行了,更改了其中一个菜单的标题。

更新: 我已经跟踪了源代码和它兑现的行是

procedure TPopupActionBar.Popup(X, Y: Integer);
...
FPopupMenu.RecreateControls;//crash here
FPopupMenu.Popup(X, Y);

但是下面的行有一个递归调用。 然后扔掉单位actnPopup.pas, 我无法找到递归调用的尾部。

它的现有代码在旧的Delphi版本下运行和编译得很好。在创建新的ManuPop并替换旧的ManuPop之后,它运行良好。但是,由于原版具有更多功能,因此设计存在损失。

仍然无能为力。

更多更新:更奇怪的是,因为我在我的机器(编译机器)上运行代码,它崩溃并烧毁,而在另一台机器(用户机器)上,它运行彩虹和蝴蝶。我没有得到!

2 个答案:

答案 0 :(得分:4)

一般指南

这是一个递归问题 请注意,调用堆栈每次都会出现完全相同的序列 这意味着某些东西导致代码从自身输入一个方法 - 即使它是间接的。

:0047fe17 TControl.Perform + $27 
:0047eb54 TControl.FontChanged + $40 
:0043797f TFont.SetData + $2F 
:00437d92 TFont.SetStyle + $36 
:004b9839 TCustomActionControl.CMFontChanged + $1D 
:0047fe17 TControl.Perform + $27 
:0047eb54 TControl.FontChanged + $40 
:004378c5 TFont.Assign + $61 
:004bf1f0 TThemedMenuItem.CalcBounds + $68 
:004b9839 TCustomActionControl.CMFontChanged + $1D 

以下简单代码说明了同样的问题:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1Click(Sender);
end;

通常,只需设置一个断点并找出该方法为重入的原因。通常这是因为:

  • 递归是故意的,但是有一个错误阻止了终止条件。
  • 或者递归是循环“触发”行为的无意的副作用。即对象B响应对象A的变化而改变其状态,反之亦然。所以关于A& A的事件B继续互相打电话。
  • 错误使用Windows消息架构。对Application.ProcessMessages非常警惕。这是一种非常危险的方法,因为它可能导致从任务/进程中间重新进入代码 - 而不是Windows消息循环的下一次迭代。

此特定问题

当然看堆栈,这似乎是递归调用自身的标准Delphi代码。但RAD开发的一个危险是设置属性值是编写代码的一种形式 - 尽管它看起来并不那样。
特定属性值可能会导致某些代码的行为略有不同,从而触发递归。

不幸的是,没有足够的信息可以提供不同的解决方案,但我可以提供一些需要检查的建议:

  • 当然,使用debug dcu进行编译可能有助于追踪问题。不要被前景阅读VCL源代码所吓倒 - 这实际上是最好的学习方式之一。
  • 您是否添加了任何动作控件?
  • 您是否正在使用任何第三方组件?
  • 当时弹出菜单是否可见之间是否存在差异?
  • 我注意到正在调用FontChanged方法,但更改标题不应该触发。
  • 如果您正在使用与PopupMenu交互的任何其他组件,请尝试一次删除或禁用它们。
  • 尝试将属性重置为默认值。这可以将dfm视为文本来完成。您在dfm中看到的大多数属性值都是非默认值。只需删除该行就会将其重置为默认值。

如果你还在苦苦挣扎

您可以提供一些其他信息来提供帮助:

  • 设置标题的示例代码,包括触发标题的事件。
  • 弹出菜单的事件处理程序
  • 以及与菜单交互的任何操作控件。
  • dfm作为相关控件的文本。

答案 1 :(得分:1)

这种情况的典型原因是一个事件处理程序,它执行一些触发相同事件处理程序的操作。因此无限递归和最终的堆栈溢出。这是你的问题很可能。

为了解决这个问题,我会回到调用堆栈的基础,找到它开始重复的位置。那里应该有线索。