I had a closer look at the "Stack trace:" table from reply #5:
[FORMS.PP] ExceptionOccurred
Sender=EAccessViolation
Exception=Access violation
Stack trace:
$00000000005D1B42 = CONTROLS$_$TCONTROL_$__$$_DESTROY + 434
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$000000000062C62E = STDCTRLS$_$TCUSTOMEDIT_$__$$_DESTROY + 78
$000000000062B12E = STDCTRLS$_$TCUSTOMMEMO_$__$$_DESTROY + 110
$000000000051ABB6 = CLASSES$_$TCOMPONENT_$__$$_DESTROYCOMPONENTS + 54
$00000000005D1C6E = CONTROLS$_$TCONTROL_$__$$_DESTROY + 734
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$00000000005D476E = CONTROLS$_$TCUSTOMCONTROL_$__$$_DESTROY + 78
$0000000000448ADE = FORMS$_$TSCROLLINGWINCONTROL_$__$$_DESTROY + 94
$000000000044A4F6 = FORMS$_$TCUSTOMFORM_$__$$_DESTROY + 278
$0000000000430ACB = SYSTEM$_$TOBJECT_$__$$_FREE + 27
$0000000000445886 = FORMS_$$_BEFOREFINALIZATION + 22
$00000000004355A9 = SYSTEM_$$_INTERNALEXIT + 89
We know, that the AV occured (during program termination), while procedure Forms.BeforeFinalization() was excecuted, which only calls Application.DoBeforeFinalization():
procedure TApplication.DoBeforeFinalization;
var
i: Integer;
begin
if Self=nil then exit;
for i := ComponentCount - 1 downto 0 do
begin
// DebugLn('TApplication.DoBeforeFinalization ',DbgSName(Components[i]));
if i < ComponentCount then
Components[i].Free;
end;
end;
This procedure calls Free() for all existing Application.Components[].
Question1:What does Application.Components[] contain?
My suspicion is, that this array contains all GUI-Controls (?) which have been created with its Parent=Application.
Can somebody confirm, whether this is correct? Or give a better answer?
I tried to guess from the "Stack trace" table, which type of GUI-Control was just trying to Free(), when the AV occured:
Stack trace:
$00000000005D1B42 = CONTROLS$_$TCONTROL_$__$$_DESTROY + 434
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$000000000062C62E = STDCTRLS$_$TCUSTOMEDIT_$__$$_DESTROY + 78
$000000000062B12E = STDCTRLS$_$TCUSTOMMEMO_$__$$_DESTROY + 110
$000000000051ABB6 = CLASSES$_$TCOMPONENT_$__$$_DESTROYCOMPONENTS + 54
$00000000005D1C6E = CONTROLS$_$TCONTROL_$__$$_DESTROY + 734
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$00000000005D476E = CONTROLS$_$TCUSTOMCONTROL_$__$$_DESTROY + 78
$0000000000448ADE = FORMS$_$TSCROLLINGWINCONTROL_$__$$_DESTROY + 94
$000000000044A4F6 = FORMS$_$TCUSTOMFORM_$__$$_DESTROY + 278
$0000000000430ACB = SYSTEM$_$TOBJECT_$__$$_FREE + 27
$0000000000445886 = FORMS_$$_BEFOREFINALIZATION + 22
$00000000004355A9 = SYSTEM_$$_INTERNALEXIT + 89
The 6 yellow lines look, as if a TForm (or its descendant) was Free'd: called are 6 Destroy's (from bottom to top: TCustomForm, TScrollingWinControl, TCustomControl, TWinControl, TControl, TComponent) which match to the Inheritance table in
https://lazarus-ccr.sourceforge.io/docs/lcl/forms/tform.html Stack trace:
$00000000005D1B42 = CONTROLS$_$TCONTROL_$__$$_DESTROY + 434
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$000000000062C62E = STDCTRLS$_$TCUSTOMEDIT_$__$$_DESTROY + 78
$000000000062B12E = STDCTRLS$_$TCUSTOMMEMO_$__$$_DESTROY + 110
$000000000051ABB6 = CLASSES$_$TCOMPONENT_$__$$_DESTROYCOMPONENTS + 54
$00000000005D1C6E = CONTROLS$_$TCONTROL_$__$$_DESTROY + 734
$00000000005BEF09 = CONTROLS$_$TWINCONTROL_$__$$_DESTROY + 457
$00000000005D476E = CONTROLS$_$TCUSTOMCONTROL_$__$$_DESTROY + 78
$0000000000448ADE = FORMS$_$TSCROLLINGWINCONTROL_$__$$_DESTROY + 94
$000000000044A4F6 = FORMS$_$TCUSTOMFORM_$__$$_DESTROY + 278
$0000000000430ACB = SYSTEM$_$TOBJECT_$__$$_FREE + 27
$0000000000445886 = FORMS_$$_BEFOREFINALIZATION + 22
$00000000004355A9 = SYSTEM_$$_INTERNALEXIT + 89
And the 4 yellow lines above look, as if a TMemo (or its descendant) was trying to Free: called are 4 Destroy's (from bottom to top: TCustomMemo, TCustomEdit, TWinControl, TControl) which match to the Inheritance table in
https://lazarus-ccr.sourceforge.io/docs/lcl/stdctrls/tmemo.htmlQuestion 2:Is this correct? Can we
rely, that the AV occured during the attempt, to Free a TForm (or its descendant), which contains (at least) 1 TMemo (or its descendant)? This would reduce the number of possible Forms in my program significantly...
Question 3:If question 2 is true: then we see, that a TMemo (or its descendant) was the very 1st GUI-Control of a Form, which was tried to Free (after freeing the Form). Can we deduce from that, that a TMemo (or its descendant)
must be the very first (or very last?) declared GUI-Control in that Form? This would reduce the number of possible Forms in my program more significantly...
If yes: very first or very last?