Forum > General
Lazarus trank: stack overflow for new revisions
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