Forum > General

Lazarus trank: stack overflow for new revisions

(1/4) > >>

zoltanleo:
Hi folks

I am getting an overflow error in my old project after updating lazarus to newer versions.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Project project1 raised exception class 'External: STACK OVERFLOW'. At address 10000E3BF
The project compiles and builds successfully. In the test project, this happens inside the loop (this happens in the onclick event for each button):

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  for i:= 0 to Pred(Panel1.ControlCount) do    if TControl(Panel1.Controls[i]).InheritsFrom(TToggleBox) then      TToggleBox(Panel1.Controls[i]).State:= cbUnchecked;
The error is observed for Lazarus revision: main-2_3-2511-gfee5b58ce2 and older.

The error is reproduced for win34/64 and gtk2_x64 (I didn't check for qt and darwin)

What happened?

Updated:
If I add an additional flag that prevents recursion in changing the component, then no error occurs


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  private    FInChanging: Boolean;  procedure TForm1.TglBoxClick(Sender: TObject);var  i: PtrInt = 0;begin  if FInChanging then Exit;  FInChanging := True;   if not TObject(Sender).InheritsFrom(TToggleBox) then Exit;   try    Memo1.Lines.Add('');    Memo1.Lines.Add(Format('====== %s.Click ======',[TToggleBox(Sender).Name]));     Memo1.Lines.Add('');      for i:= 0 to Pred(Panel1.ControlCount) do      if TControl(Panel1.Controls[i]).InheritsFrom(TToggleBox) then        begin          TToggleBox(Panel1.Controls[i]).State:= cbUnchecked;          Memo1.Lines.Add(Format('Panel1.Controls[%d] State property changed to ''cbUnchecked'' value (%s)',          [i, FormatDateTime('hh:nn:ss.zzz',Now)]));        end;     TToggleBox(Sender).State:= cbChecked;    Memo1.Lines.Add(Format('%s State property changed to ''cbChecked'' value (%s)',    [TToggleBox(Sender).Name, FormatDateTime('hh:nn:ss.zzz',Now)]));  finally    FInChanging:= False;  end;end;                                      

paweld:
Modifying the state of TToggleBox triggers the OnClick event, so set TToggleBox.OnClick to nil when changing the state, or try to avoid changing the status in the OnClick event, as it falls into an infinite loop.
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.TglBoxClick(Sender: TObject);var  i: PtrInt = 0;begin  if not TObject(Sender).InheritsFrom(TToggleBox) then Exit;   Memo1.Lines.Add('');  Memo1.Lines.Add(Format('====== %s.Click ======',[TToggleBox(Sender).Name]));   Memo1.Lines.Add('');    for i:= 0 to Pred(Panel1.ControlCount) do    if TControl(Panel1.Controls[i]).InheritsFrom(TToggleBox) then      begin        TToggleBox(Panel1.Controls[i]).OnClick:= nil;   //<--Add this        TToggleBox(Panel1.Controls[i]).State:= cbUnchecked;        TToggleBox(Panel1.Controls[i]).OnClick:= @TglBoxClick;   //<--and this        Memo1.Lines.Add(Format('Panel1.Controls[%d] State property changed to ''cbUnchecked'' value (%s)',        [i, FormatDateTime('hh:nn:ss.zzz',Now)]));      end;   TToggleBox(Sender).OnClick:= nil;   //<--and this  TToggleBox(Sender).State:= cbChecked;  TToggleBox(Sender).OnClick:= @TglBoxClick;   //<--and this  Memo1.Lines.Add(Format('%s State property changed to ''cbChecked'' value (%s)',  [TToggleBox(Sender).Name, FormatDateTime('hh:nn:ss.zzz',Now)]));end;             

PascalDragon:
Or you could check inside the loop whether the control is the Sender and not change its State then.

Arioch:
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39914

https://forum.lazarus.freepascal.org/index.php/topic,60430.0.html

zoltanleo:
Thanks for answers.

Can I consider the current behavior of the component as normal?

Navigation

[0] Message Index

[#] Next page

Go to full version