Recent

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

Shebuka

  • Sr. Member
  • ****
  • Posts: 415
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: 2103
    • 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: 415
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: 415
Re: VirtualTreeView destroying itself right after creation
« Reply #3 on: Today at 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: 2103
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #4 on: Today at 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: Today at 03:11:10 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2103
    • havefunsoft.com
Re: VirtualTreeView destroying itself right after creation
« Reply #5 on: Today at 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