GTK2: access to freed memory in DestroyWidget

Original Reporter info from Mantis: Martin @martin_frb
  • Reporter name: Martin Friebe

Description:

See attached valgrind trace

lcl\interfaces\gtk2\gtk2proc.inc
line 4205

--------------
Some guesswork of me. Please verify against the valgrind trace.
See 2 comments in code.
Those comments are what I deducted from the valgrind trace. They may be wrong / need verification.

procedure DestroyWidget(Widget: PGtkWidget);
var
  Info: PWidgetInfo;
  AWinControl: TWinControl;
  Mess: TLMessage;
begin
  //DebugLn(['DestroyWidget A ',GetWidgetDebugReport(Widget)]);
  {$IFDEF DebugLCLComponents}
  if DebugGtkWidgets.FindInfo(Widget)=nil then
    DebugLn(['DestroyWidget ',GetWidgetDebugReport(Widget)]);
  {$ENDIF}
  Info:=GetWidgetInfo(Widget);
  if Info<>nil then begin
    if (Info^.LCLObject is TWinControl) then begin
      AWinControl:=TWinControl(Info^.LCLObject);
      if AWinControl.HandleAllocated
      and ({%H-}PGtkWidget(AWinControl.Handle)=Widget) then begin
        // send the LM_DESTROY message before destroying the widget
        FillChar(Mess{%H-},SizeOf(Mess),0);
        Mess.msg := LM_DESTROY;
        DeliverMessage(Info^.LCLObject, Mess);
      end;
    end;
    FreeWidgetInfo(Widget);    ///////////////////////////////////////////////// The INFO is freed here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  end;
  {$IFDEF DebugLCLComponents}
  DebugGtkWidgets.MarkDestroyed(Widget);
  {$ENDIF}
  gtk_widget_destroy(Widget);  ////////////////////////////////////////// this leads to a callback to gtkdestroyCB which accesses the INFO <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  //DebugLn(['DestroyWidget B']);
end;

Steps to reproduce:

One way to reproduce is using the debugger locals windows. Not sure of the exact other circumstances. May need to display some values / change some values ?

Mantis conversion info:

  • Mantis ID: 38332
  • OS: Ubuntu 20
  • OS Build: 20
  • Build: 64346
  • Platform: Linux
  • Version: 2.1 (SVN)
  • Monitored by: » AntonK (Anton Kavalenka)