Lazarus

Programming => Widgetset => Cocoa => Topic started by: MISV on June 23, 2019, 02:12:53 pm

Title: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: MISV on June 23, 2019, 02:12:53 pm
This started when switching to Cocoa, but I just ignore it until now...

Whenever my program closes I get error

Quote
Debugger stopped with reason: EXC_BAD_ACCESS (code=1, address=0x0)

In file 'winapi.inc' at line 180:
Result := WidgetSet.DeleteObject(GDIObject):

It appears to originate:
TCustomBitmap.Destroy->Inherited
TRasterImage.Destroy->FSharedImage.Release
TSharedImage.Release->FreeHandle
TSharedCustomBitmap.FreeHandle->Inherited
TSharedRasterImages.FreeHandle->DeleteObject(FHandle)
(winapi.inc) DeleteObject(GDIObject: HGDIOBJ): Boolean;

But any ideas? Of what I should try? This is a quite large application (about half million lines of own code - then add Indy, LCL, FPC, Virtual Treeview) with a ton of imagelists and what not, so it will be extremely tedious to remove one a a time :/

But if there maybe is anything I could check runtime (e.g. to write code to check up on all imagelists, images etc. are okay) I think maybe that could be a way forward?

...

In release builds running outside debugger I do not see this error, but I am looking into this since I have a user reporting that the program froze while closing...
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: skalogryz on June 23, 2019, 02:29:42 pm
address = 0x0
no widgetset?! or double freeing
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: MISV on June 23, 2019, 10:50:27 pm
I use Cocoa as widgetset. It is limited what my code does of bitmap freeing.

For what it is worth - this problem does/did not occur on Lazarus/Carbon and Delphi

If i could just see what initiates the call to the initial TCustomBitmap.Destroy->Inherited but the callstack does not reveal
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: skalogryz on June 23, 2019, 10:57:32 pm
it's TObject.free
a sample project then?
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: MISV on June 23, 2019, 11:44:23 pm
Funny thing happen - clicking like a manic in the debugger - callstack window reveals more (where before it simply stated an address)

It appears to originate:
:FFF5A01911A - (anonymous namespalce)::AutoreleasePoolPage::pop(void*)
(cocoabuttons) TCocoaButton.dealloc -> if Assigned (Glyph) then FreeAndNil(Glyph);
:1000469D7 - SYSUTILS_$$_FreeAndNil$formal
:1000126E5 - SYSTEM$_$TObject_$_$$_FREE
TCustomBitmap.Destroy->Inherited
TRasterImage.Destroy->FSharedImage.Release
TSharedImage.Release->FreeHandle
TSharedCustomBitmap.FreeHandle->Inherited
TSharedRasterImages.FreeHandle->DeleteObject(FHandle)
(winapi.inc) DeleteObject(GDIObject: HGDIOBJ): Boolean;

...

I will see if I can create a demo project... Alternatively I may try create some code that iterates all controls and removes the glyph... then see if that triggers the error in one of the buttons... And that way I may be able to see what is causing the issue?

Conclusion:
Sofar unsuccessful testing in a meaningful way as
TBitBtn(AControl).Glyph.Clear, TBitBtn(AControl).Glyph.Free, TBitBtn(AControl).Glyph := nil
all do not appear to make any different (all glyphs still show)

I may be too tired and missing something so will return to this tomorrow. Had hoped I could somehow trigger the error runtime and point it down to a specific glyph used, button properties or similar.
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: skalogryz on June 24, 2019, 01:36:32 am
what operations on glyphs you do in runtime ?
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: MISV on June 24, 2019, 02:28:04 am
As mentioned, iterating over all controls doing
Code: Pascal  [Select][+][-]
  1. TBitBtn(AControl).Glyph.Clear;
  2. TBitBtn(AControl).Glyph.Free;
  3. TBitBtn(AControl).Glyph := nil;
  4.  
did not provoke any runtime error.



However - if you are asking if I am doing anyhing *else* that might explain why I am seeing this error (and others not) I have searched my source and upon startup I:

1) I do height adjustments to adjust to platform standards - http://wiki.freepascal.org/Cocoa_Internals/Buttons
2) I set GlyphShowMode to gsmAlways... and then if a supposed-to-be-a-square button I set to blGlyphBottom.
3) And then if supposed-to-be-a-square button I make sure to set width same as height.
4) If button has been resized in step #1 or #3 I adjust top/left accordingly.
5) If TBitBtn has Glyph <> nil I *Hide* and then *Show* the button (had a problem with glyphs otherwise appearing invisible on Cocoa)

Above is for Cocoa/Lazarus codepath. My code also has "codepaths" for Carbon/Lazarus and Windows/Delphi. (I still compile my entire source + DFM on both Delphi and Lazarus. For the last "polish" I have added the runtime adjustments so e.g. fit macOS Cocoa UI best possible. Some of it has also been by trial-error to see what gave the best/correct look. I do this for many of the controls I use.)

Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: skalogryz on June 24, 2019, 03:31:56 am
i'd think the problem is not with glyphs, but rather the destruction of controls.
Title: Re: Track down EXC_BAD_ACCESS in WidgetSet.DeleteObject(GDIObject)
Post by: MISV on June 26, 2019, 10:15:48 am
This issue seems solved in the latest update as well....
TinyPortal © 2005-2018