2
votes

small piece of the stack

: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

and it goes on and on ...

the last code executed that i generated was, changing one of the menu's captions.

UPDATE: i have traced the source code and the line it cashed on is

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

however there is a recursive call the line below. and going throw the unit actnPopup.pas, i can't find the tail of the recursive call.

its an existing code that worked and compiled well under older Delphi version. After A new ManuPop was created , and replaced the old one, it works well. However, there is a loss in the design as the original had more features into it.

Still clueless.

more updates: something even more oddish, as i run the code on my machine(the compiling machine), it crash and burn, and on another machine(a user machine), it run with rainbows and butterflies. i don't get!

2
Perhaps the best you can do is build your project with debug dcu's and then set a break-point in your code that triggers this. Somehow this loop is triggered and stepping through the source code might reveal why this happens.Ritsaert Hornstra
Do you have any events tied to that popup menu, like ... say... changing the font of an item depending on something?Lasse V. Karlsen
no font change. only caption and image change. the popup is TPopupActionBar.none

2 Answers

4
votes

General Guidelines

This is a recursion problem.
Notice from the call stack that the exact same sequence occurs each time.
This means that something is causing code to enter a method from itself - even if it is indirectly.

: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 

The following simple code illustrates the same kind of problem:

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

In general, one would simply set a breakpoint and find out why the method is re-entrant. Usually this is because:

  • The recursion is intentional, but there is a bug preventing the terminating condition being reached.
  • Or the recursion is an unintentional side-effect of circular 'trigger' behaviour. I.e. Object B changes its state in response to a change in Object A, and vice versa. So the events on A & B keep calling each other.
  • Incorrect use of Windows Message Architecture. Be very wary of Application.ProcessMessages. It is a very dangerous method to use beause it can cause re-entry into code from the middle of a task/process - as opposed to the next iteration of the Windows Message Loop.

This Specific Problem

Of course looking the stack, this appears to be standard Delphi code recursively calling itself. But one of the dangers of RAD development is that setting property values is a form of writing code - even though it doesn't seem that way.
It is possible that a particular property value may cause some of the code to behave slightly differently, thereby triggering the recursion.

Unfortunately there isn't enough information for a difinitive solution, but I can offer suggestions of things to check:

  • Of course, compiling with debug dcu's might help to track down the problem. Don't be intimidated by the prospect reading VCL Source code - it's actually one of the best ways to learn.
  • Have you added any Action Controls?
  • Are you making use of any third party components?
  • Is there a difference between whether the Popup Menu is visible at the time or not?
  • I notice that the FontChanged method is being called, yet changing a caption should not trigger that.
  • If you are using any additional components that would interact with the PopupMenu, try deleting or disabling them one at a time.
  • Try resetting properties back to their default values. This can be done viewing the dfm as text. Most property values you see in the dfm will be the non-default value. Simply deleting the line will reset it back to default.

If You're Still Struggling

You can provide some additional information to help out:

  • Sample code that sets the caption, including the event that triggers it.
  • The event handlers for the Popup Menu
  • and any Action Controls that interact with the menu.
  • The dfm as text of the relevant controls.
1
votes

The typical cause for something like this is an event handler that performs some action that triggers the same event handler. Hence the infinite recursion and resulting stack overflow. There's a very high probability that's your problem.

To work it out, I'd look back right to the base of the call stack and find where it starts repeating itself. There should be clues there.