Recent

Author Topic: VirtualTreeView destroying itself right after creation  (Read 997 times)

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
VirtualTreeView destroying itself right after creation
« on: May 16, 2019, 07:30:20 pm »
Hello, inspired by recent developments in LLDB and LCLCocoa I've updated my environment to all latest: Lazarus 2.0.2, RichMemo from lazarus-ccr-svn-r6911, lclextensions from luipack-master and VirtualTreeView from VirtualTreeView-Lazarus-lazarus-v5.

All was still building and working nicely on LCLCarbon 32bit.

Then I've switched to LCLCocoa 64bit and I have problems...

I have a form with VirtualStringTree that is design based, but allocated runtime with FMyForm := TMyForm.Create(AParent) (AParent is main form Self passed from client.pas all the chain up to windowmanager.pas). First debugger was stopping in TCustomVirtualStringTree creation and throwing a Range check error. If I ignore that error it stops in TCustomVirtualStringTree destruction throwing access violation, here is the stack trace:

Code: Pascal  [Select]
  1. #0 DESTROY(0x0000000103fcf350, 0x0000000000000000) at VirtualTrees.pas:12383
  2. #1 DESTROY(0x0000000103fcf350, 44490268882320604) at VirtualTrees.pas:34008
  3. #2 CREATE(0x0000000103fcf350, 44490268882320604, 0x0000000103fccaf0) at VirtualTrees.pas:33438
  4. #3 CLASSES$_$TREADER_$__$$_READCOMPONENT$TCOMPONENT$$TCOMPONENT at :-1
  5. #4 CLASSES$_$TREADER_$__$$_READDATA$TCOMPONENT at :-1
  6. #5 CLASSES$_$TCOMPONENT_$__$$_READSTATE$TREADER at :-1
  7. #6 READSTATE(0x0000000103fccaf0, 0x00000001045f4ee0) at control.inc:3947
  8. #7 CLASSES$_$TREADER_$__$$_READROOTCOMPONENT$TCOMPONENT$$TCOMPONENT at :-1
  9. #8 INITCOMPONENT(0x00007ffeefbfebf0, 0x0000000100d04380) at lresources.pp:3156
  10. #9 INITLAZRESOURCECOMPONENT(0x0000000103fccaf0, 0x0000000100ae8490) at lresources.pp:3183
  11. #10 INITRESOURCECOMPONENT(0x0000000103fccaf0, 0x0000000100ae8490) at lresources.pp:804
  12. #11 PROCESSRESOURCE(0x0000000103fccaf0) at customform.inc:2069
  13. #12 CREATE(0x0000000103fccaf0, 0x0000000000000000, 0x0000000103f93bd0) at customform.inc:2057
  14. #13 CREATE(0x0000000103fccaf0, 0x0000000000000001, 0x0000000103f93bd0) at customform.inc:3183
  15. #14 CREATEFIXEDWINDOWS(0x0000000103f971d0) at windowmanager.pas:444
  16. #15 CREATE(0x0000000103f96c90, 0x0000000000000001, 0x0000000103f96a10, 0x0000000103f93bd0) at guimanager.pas:466
  17. #16 CREATE(0x0000000103f96a10, 0x0000000000000001, 0x0000000103f93bd0) at bigboss.pas:453
  18. #17 FORMCREATE(0x0000000103f93bd0, 0x0000000103f93bd0) at client.pas:225
  19. #18 DOCREATE(0x0000000103f93bd0) at customform.inc:939
  20. #19 AFTERCONSTRUCTION(0x0000000103f93bd0) at customform.inc:149
  21. #20 CREATE(0x0000000103f93bd0, 44490268882320604, 0x0000000103f92b50) at customform.inc:3184
  22. #21 CREATEFORM(0x0000000103f92b50, 0x0000000100af0f00, <unavailable>) at application.inc:2241
  23. #22 PASCALMAIN at easymeetingClient.lpr:18
  24. #23 FPC_SYSTEMMAIN at :-1
  25. #24 start at :-1
  26. #25 start at :-1

But even if I comment out the creation of the form with VirtualStringTree then the debugger goes in error: Debugger stopped with reason: EXC_BAD_ACCESS (code=1, address=0x0)

How can I debug this and understand whats brokening?
« Last Edit: May 17, 2019, 09:45:39 am by Shebuka »

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2267
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #1 on: May 22, 2019, 07:19:50 pm »
seems like it's crashing on loading .lfm file.
how does .lfm look for this virtualtree?
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
Re: VirtualTreeView destroying itself right after creation
« Reply #2 on: May 23, 2019, 05:23:13 pm »
seems like it's crashing on loading .lfm file.
how does .lfm look for this virtualtree?

It's a simple form with a TVirtualStringTree and Align = alClient:

Code: Pascal  [Select]
  1. object Frm_UsersO2M: TFrm_UsersO2M
  2.   Tag = 205
  3.   Left = 460
  4.   Height = 266
  5.   Top = 655
  6.   Width = 782
  7.   Caption = 'Users'
  8.   ClientHeight = 266
  9.   ClientWidth = 782
  10.   OnClose = FormClose
  11.   OnCreate = FormCreate
  12.   OnKeyDown = FormKeyDown
  13.   OnShow = FormShow
  14.   Position = poDefaultPosOnly
  15.   LCLVersion = '2.1.0.0'
  16.   object VST_Users: TVirtualStringTree
  17.     Left = 0
  18.     Height = 266
  19.     Top = 0
  20.     Width = 782
  21.     Align = alClient
  22.     DefaultText = 'Node'
  23.     DragType = dtVCL
  24.     Header.AutoSizeIndex = 0
  25.     Header.Columns = <    
  26.       item
  27.         Position = 0
  28.         Text = 'hdUserName'
  29.         Width = 326
  30.       end    
  31.       item
  32.         Alignment = taCenter
  33.         Position = 1
  34.         Text = 'hdBookingOrder'
  35.         Width = 100
  36.       end    
  37.       item
  38.         Alignment = taCenter
  39.         Position = 2
  40.         Text = 'hdActiveChannel'
  41.         Width = 84
  42.       end    
  43.       item
  44.         Position = 3
  45.         Text = 'hdGatewayTerminal'
  46.         Width = 130
  47.       end    
  48.       item
  49.         Alignment = taCenter
  50.         Position = 4
  51.         Text = 'hdGetaway'
  52.         Width = 66
  53.       end    
  54.       item
  55.         Alignment = taCenter
  56.         Position = 5
  57.         Text = 'hdRecording'
  58.         Width = 76
  59.       end>
  60.     Header.DefaultHeight = 17
  61.     Header.Height = 17
  62.     Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowHint, hoShowSortGlyphs, hoVisible]
  63.     Indent = 0
  64.     ParentShowHint = False
  65.     ShowHint = True
  66.     TabOrder = 0
  67.     TreeOptions.PaintOptions = [toHideFocusRect, toShowButtons, toShowDropmark, toShowHorzGridLines, toShowRoot, toShowVertGridLines, toThemeAware, toUseBlendedImages]
  68.     TreeOptions.SelectionOptions = [toFullRowSelect, toRightClickSelect]
  69.     OnBeforeCellPaint = VST_UsersBeforeCellPaint
  70.     OnCompareNodes = VST_UsersCompareNodes
  71.     OnGetText = VST_UsersGetText
  72.     OnHeaderClick = VST_UsersHeaderClick
  73.   end
  74. end

The Range check error exception is raised by this:

CF_VTREFERENCE := ClipboardRegisterFormat(CFSTR_VTREFERENCE);

in InitializeGlobalStructures, line 5481 in /Developer/lazarus/components/virtualtreeview/VirtualTrees.pas. Debugger was stopping here with Lazarus 2.0.2, but with trunk it's not catched anymore...

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
Re: VirtualTreeView destroying itself right after creation
« Reply #3 on: June 17, 2019, 12:15:43 pm »
I've managed to make it build without raising Range check error exception by doing this:

Removing spaces in CFSTR_* constants, like this:
Code: Pascal  [Select]
  1.   CFSTR_VIRTUALTREE = 'VirtualTreeData';
  2.   CFSTR_VTREFERENCE = 'VirtualTreeReference';
  3.   CFSTR_HTML = 'HTMLFormat';
  4.   CFSTR_RTF = 'RichTextFormat';
  5.   CFSTR_RTFNOOBJS = 'RichTextFormatWithoutObjects';
  6.   CFSTR_CSV = 'CSV';
fixed the exception in the CF_VTREFERENCE := ClipboardRegisterFormat(CFSTR_VTREFERENCE); but was still raising it in CF_* := RegisterVTClipboardFormat(CFSTR_*, *+);

So, for now, I've commented them out:
Code: Pascal  [Select]
  1.   //// Clipboard format registration.
  2.   //// Native clipboard format. Needs a new identifier and has an average priority to allow other formats to take over.
  3.   //// This format is supposed to use the IStream storage format but unfortunately this does not work when
  4.   //// OLEFlushClipboard is used. Hence it is disabled until somebody finds a solution.
  5.   //CF_VIRTUALTREE := RegisterVTClipboardFormat(CFSTR_VIRTUALTREE, TBaseVirtualTree, 50, TYMED_HGLOBAL {or TYMED_ISTREAM});
  6.   //// Specialized string tree formats.
  7.   //CF_HTML := RegisterVTClipboardFormat(CFSTR_HTML, TCustomVirtualStringTree, 80);
  8.   //CF_VRTFNOOBJS := RegisterVTClipboardFormat(CFSTR_RTFNOOBJS, TCustomVirtualStringTree, 84);
  9.   //CF_VRTF := RegisterVTClipboardFormat(CFSTR_RTF, TCustomVirtualStringTree, 85);
  10.   //CF_CSV := RegisterVTClipboardFormat(CFSTR_CSV, TCustomVirtualStringTree, 90);

Strange thing, the predefined clipboard formats are not rising any exception:
Code: Pascal  [Select]
  1.   RegisterVTClipboardFormat(CF_TEXT, TCustomVirtualStringTree, 100);
  2.   RegisterVTClipboardFormat(CF_UNICODETEXT, TCustomVirtualStringTree, 95);

For now, it's ok cause I'm not using the clipboard in our application, but still, any ideas of why this is happening?

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2267
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #4 on: June 17, 2019, 03:08:30 pm »
For now, it's ok cause I'm not using the clipboard in our application, but still, any ideas of why this is happening?
Yes. The issue is with VirtualTree component sources.
Raises the exception, because ranges are in fact violated on registering a new clipboard format.

They're violated because CF_xxx variables are declared as WORD type (2-bytes in size). While LCL introduces a special TClipboardFormat (pointer size).
While "2-byte" happens (strictly speaking it's a matter of luck) to work on WinAPI and Gtk/Qt systems, it fails right away on Cocoa. (because Cocoa generated TClipboardFormat values are way beyond 2-byte size).

So, in order to make a "quick-fix" you can change the declaration of CF_xx variables, from:
Code: Pascal  [Select]
  1. var // Clipboard format IDs used in OLE drag'n drop and clipboard transfers.
  2.   CF_VIRTUALTREE,
  3.   CF_VTREFERENCE,
  4.   CF_VRTF,
  5.   CF_VRTFNOOBJS,   // Unfortunately CF_RTF* is already defined as being
  6.                    // registration strings so I have to use different identifiers.
  7.   CF_HTML,
  8.   CF_CSV: Word;
  9.  
to
Code: Pascal  [Select]
  1. var // Clipboard format IDs used in OLE drag'n drop and clipboard transfers.
  2.   CF_VIRTUALTREE,
  3.   CF_VTREFERENCE,
  4.   CF_VRTF,
  5.   CF_VRTFNOOBJS,   // Unfortunately CF_RTF* is already defined as being
  6.                    // registration strings so I have to use different identifiers.
  7.   CF_HTML,
  8.   CF_CSV: TClipboardFormat;
  9.  


BUT, it will eventually fail in run-time, because clipboard Format is often treated as WORD.
I tried to patch VT code (the patch is attached to this message) and replace any clipboard-format related declarations by TClipboardFormat, but I'm not sure if it's enough
« Last Edit: June 17, 2019, 03:11:10 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2267
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #5 on: June 17, 2019, 03:17:43 pm »
btw, you really want to bugreport the issue for the virtualtreeview maintainer.
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
Re: VirtualTreeView destroying itself right after creation
« Reply #6 on: June 18, 2019, 12:52:51 pm »
...
Raises the exception, because ranges are in fact violated on registering a new clipboard format.

They're violated because CF_xxx variables are declared as WORD type (2-bytes in size). While LCL introduces a special TClipboardFormat (pointer size).
While "2-byte" happens (strictly speaking it's a matter of luck) to work on WinAPI and Gtk/Qt systems, it fails right away on Cocoa. (because Cocoa generated TClipboardFormat values are way beyond 2-byte size).
...

I've actually also changed Word with TClipboardFormat but it was still rising exception so I've not included this in the 'fix' post...

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2267
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #7 on: June 18, 2019, 02:44:32 pm »
I've actually also changed Word with TClipboardFormat but it was still rising exception so I've not included this in the 'fix' post...
did you change other variables that might be used to carry the format over?

try this - backup all your local changes.
revert the virtualtree files and try to apply the patch I provided.

let me know, if it still crashes
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
Re: VirtualTreeView destroying itself right after creation
« Reply #8 on: June 19, 2019, 02:53:51 pm »
Your patch is for laz.virtualtree.pas version of VTV, but I'm using a VTV version from maintainers official GitHub repository at https://github.com/blikblum/VirtualTreeView-Lazarus/tree/lazarus-v5 so I've applied your patch manually by copy&paste. But it's still crashing.

I've also tried to take the laz.virtualtree.pas, apply the patch, remove spaces from CFSTR_VTREFERENCE, rename it to virtualtree.pas and find/replace "laz." and "laz_" with "" (nothing). Still crashing. Also if I comment the crashing RegisterVTClipboardFormats the VTV is not drawing itself at all, I see only a black stripe half the height of the component (I'm in Drak mode, so maybe it's a white stripe in Light mode).

p.s. I've added the issue to the Issues page on GitHub of blikblum (Luiz Américo, the maintainer).

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2267
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #9 on: June 19, 2019, 03:15:11 pm »
Your patch is for laz.virtualtree.pas version of VTV, but I'm using a VTV version from maintainers official GitHub repository at https://github.com/blikblum/VirtualTreeView-Lazarus/tree/lazarus-v5 so I've applied your patch manually by copy&paste. But it's still crashing.
please try a different patch attached to the same issue

(I'm in Drak mode, so maybe it's a white stripe in Light mode).
seems like Apple did the right choice of introducing Dark mode. Everybody is using it :)
« Last Edit: June 19, 2019, 03:27:08 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Shebuka

  • Sr. Member
  • ****
  • Posts: 422
Re: VirtualTreeView destroying itself right after creation
« Reply #10 on: June 19, 2019, 06:01:08 pm »
Your patch is for laz.virtualtree.pas version of VTV, but I'm using a VTV version from maintainers official GitHub repository at https://github.com/blikblum/VirtualTreeView-Lazarus/tree/lazarus-v5 so I've applied your patch manually by copy&paste. But it's still crashing.
please try a different patch attached to the same issue

Seems to work perfectly now!