Recent

Author Topic: Questions about call stack in grids.pas  (Read 3848 times)

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Questions about call stack in grids.pas
« on: December 26, 2018, 11:18:47 am »
Hi

I'm trying to find a bug encountered using the TCustomStringGrid component.
Starting with a TCustomStringGrid having 2 rows and 2 columns, my application display a text in Cells [1,1].

During this operation, there is sometimes an attempt to get the value of Cells[1,2] which doesn't exist, and obviously this raises an exception.

Previously the grid had 3 rows, but the 3rd one was removed (using DeleteRowCol) before I try to display in Cells[1,1].  I suspect something not properly cleared in relation to Row 2, but don't find anything.

The call stack is :

Code: Pascal  [Select][+][-]
  1. #0 fpc_raiseexception at :0
  2. #1 GETCELLS(0x11ed2b50, 1, 2) at grids.pas:9894
  3. #2 GETCELLS(0x11e46670, 1, 2) at grids.pas:10888
  4. #3 SETEDITTEXT(0x11e46670, 1, 2, 0xa017218 '6,00') at grids.pas:11424
  5. #4 EDITORTEXTCHANGED(0x11e46670, 1, 2, 0xa017218 '6,00') at grids.pas:8337
  6. #5 CHANGE(0x11e480b0) at grids.pas:10142
  7. #6 TEXTCHANGED(0x11e480b0) at include\customedit.inc:644
  8. #7 TEXTCHANGED(0x11e480b0) at maskedit.pp:1604
  9. #8 CMTEXTCHANGED(0x11e480b0, {MSG = 45074, WPARAM = 0, LPARAM = 0, RESULT = 0, WPARAMLO = 0, WPARAMHI = 0, WPARAMFILLER = {FILLER = {0, 0, 0, 0}}, LPARAMLO = 0, LPARAMHI = 0, LPARAMFILLER = {FILLER = {0, 0, 0, 0}}, RESULTLO = 0, RESULTHI = 0, RESULTFILLER = {FILLER = {0, 0, 0, 0}}}) at include\control.inc:1203
  10. #9 SYSTEM$_$TOBJECT_$__$$_DISPATCH$formal at :0
  11. #10 ?? at :0
  12. #11 WNDPROC(0x11e480b0, {MSG = 45074, WPARAM = 0, LPARAM = 0, RESULT = 0, WPARAMLO = 0, WPARAMHI = 0, WPARAMFILLER = {FILLER = {0, 0, 0, 0}}, LPARAMLO = 0, LPARAMHI = 0, LPARAMFILLER = {FILLER = {0, 0, 0, 0}}, RESULTLO = 0, RESULTHI = 0, RESULTFILLER = {FILLER = {0, 0, 0, 0}}}) at include\wincontrol.inc:5425
  13. #12 WNDPROC(0x11e480b0, {MSG = 45074, WPARAM = 0, LPARAM = 0, RESULT = 0, WPARAMLO = 0, WPARAMHI = 0, WPARAMFILLER = {FILLER = {0, 0, 0, 0}}, LPARAMLO = 0, LPARAMHI = 0, LPARAMFILLER = {FILLER = {0, 0, 0, 0}}, RESULTLO = 0, RESULTHI = 0, RESULTFILLER = {FILLER = {0, 0, 0, 0}}}) at include\customedit.inc:528
  14. #13 WNDPROC(0x11e480b0, {MSG = 45074, WPARAM = 0, LPARAM = 0, RESULT = 0, WPARAMLO = 0, WPARAMHI = 0, WPARAMFILLER = {FILLER = {0, 0, 0, 0}}, LPARAMLO = 0, LPARAMHI = 0, LPARAMFILLER = {FILLER = {0, 0, 0, 0}}, RESULTLO = 0, RESULTHI = 0, RESULTFILLER = {FILLER = {0, 0, 0, 0}}}) at grids.pas:10132
  15. #14 PERFORM(0x11e480b0, 45074, 0, 0) at include\control.inc:1581
  16. #15 REALSETTEXT(0x11e480b0, 0xa017218 '6,00') at include\control.inc:5030
  17. #16 REALSETTEXT(0x11e480b0, 0xa017218 '6,00') at include\wincontrol.inc:8354
  18. #17 REALSETTEXT(0x11e480b0, 0xa017218 '6,00') at include\customedit.inc:569
  19. #18 REALSETTEXT(0x11e480b0, 0xa017218 '6,00') at maskedit.pp:1077
  20. #19 SETTEXT(0x11e480b0, 0xa017218 '6,00') at include\control.inc:5055
  21. #20 MSG_SETVALUE(0x11e480b0, {LCLMSG = {MSG = 66859, WPARAM = 1, LPARAM = 1, RESULT = 9, WPARAMLO = 1, WPARAMHI = 0, WPARAMFILLER = {FILLER = {0, 0, 0, 0}}, LPARAMLO = 1, LPARAMHI = 0, LPARAMFILLER = {FILLER = {0, 0, 0, 0}}, RESULTLO = 9, RESULTHI = 0, RESULTFILLER = {FILLER = {0, 0, 0, 0}}}, GRID = 0x11e46670, COL = 1, ROW = 1, VALUE = 0xa017218 '6,00', CELLRECT = {LEFT = 144042720, TOP = 0, RIGHT = 144042640, BOTTOM = 0, TOPLEFT = {X = 144042720, Y = 0}, BOTTOMRIGHT = {X = 144042640, Y = 0}, VECTOR = {144042720, 0, 144042640, 0}}, OPTIONS = 167568708}) at grids.pas:10244
  22. #21 SYSTEM$_$TOBJECT_$__$$_DISPATCH$formal at :0
  23. #22 ?? at :0
  24. #23 GETEDITTEXT(0x895ea90, 300181104, 167568708) at grids.pas:11311
  25. #24 UPDATECELL(0x895eae0) at grids.pas:10941
  26. #25 SETCELLS(0x11e46670, 1, 1, 0xa011a98 '6,00') at grids.pas:10953

The source (2.0.0-RC2, revision 59373) is :

Code: Pascal  [Select][+][-]
  1. procedure TCustomStringGrid.SetCells(ACol, ARow: Integer; const AValue: string);
  2.   procedure UpdateCell;
  3.   begin
  4.     if EditorMode and (aCol=FCol)and(aRow=FRow) and
  5.       not (gfEditorUpdateLock in GridFlags) then
  6.     begin
  7.       EditorDoSetValue;
  8.     end;
  9.     InvalidateCell(aCol, aRow);
  10.   end;
  11. var
  12.   C: PCellProps;
  13. begin
  14.   C:= FGrid.Celda[aCol,aRow];
  15.   if C<>nil then begin
  16.     if C^.Text<>nil then
  17.       StrDispose(C^.Text);
  18.     C^.Text:=StrNew(pchar(aValue));
  19.     UpdateCell;
  20.     FModified := True;
  21.   end else begin
  22.     if AValue<>'' then begin
  23.       New(C);
  24.       C^.Text:=StrNew(pchar(Avalue));
  25.       C^.Attr:=nil;
  26.       C^.Data:=nil;
  27.       FGrid.Celda[aCol,aRow]:=C;
  28.       UpdateCell;
  29.       FModified := True;
  30.     end;
  31.   end;
  32. end;


Reading the source, In line 10941, there is a call to EditorDoSetValue.

My questions are :
  - why is there no line in the stack for the call to EditorDoSetValue
  - what is meaning "?? at :0" after the call to GetEditText. in #22
  - Is there a compilation option to show exactly the called routines ?
  - How or where can I see the exact reason why the stack ends with GETCELLS(0x11ed2b50, 1, 2)

Currently my Compilation options are starting with :

Code: Pascal  [Select][+][-]
  1. -MObjFPC
  2. -Scahi
  3. -Cirot
  4. -gs
  5. -gl
  6. -WG
  7. -l
  8. -vewnhibq
  9. -vm5024
  10.  
(I haven't listed the -F )

Thanks for help !
« Last Edit: December 27, 2018, 01:01:39 pm by tintinux »
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Questions about call stack in grids.pas
« Reply #1 on: December 26, 2018, 12:31:24 pm »
  - why is there no line in the stack for the call to EditorDoSetValue
Not sure but may be EditorDoSetValue is INLINE.  Should see the declaration though.
  - what is meaning "?? at :0" after the call to GetEditText. in #22
The "??" means that the debugger doesn't has information enough to identify the procedure/funcion/routine.   This happens with the RTL or calls to the operating system or any other library compiled without debug information.
  - Is there a compilation option to show exactly the called routines ?
Standar debug options should be enough.
  - How or where can I see the exact reason why the stack ends with GETCELLS(0x11ed2b50, 1, 2)
GETCELLS is in the top of the stack.  That's all. "#0 fpc_raiseexception at :0" means the exception was raised (or re-raised) by the RTL and the compiler doesn't has information enough to identify the origin.
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9908
  • Debugger - SynEdit - and more
    • wiki
Re: Questions about call stack in grids.pas
« Reply #2 on: December 26, 2018, 12:44:26 pm »
Sometimes functions (kernel or rtl) like _DISPATCH are compiled without "stackframe"

Then the debugger can not read the stack around them. What happens is, that they hide the next caller from the stack. So you then miss one line.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: Questions about call stack in grids.pas
« Reply #3 on: December 26, 2018, 09:49:15 pm »
could it be possible the EDITOR was enabled on a cell when this happened ?
The only true wisdom is knowing you know nothing

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #4 on: December 27, 2018, 09:07:07 am »
Quote from: jamie
could it be possible the EDITOR was enabled on a cell when this happened ?
Yes, I think it is the cause of the issue.
A cell is edited in row 2, then the row 2 is deleted, and when something is later written in the Row 1 there is an attempt to get the value of the previously edited cell in Row 2.
As a workaround, I have tried unsuccesfully to disable the editor and to process messages, before deleting row.
Maybe there is a temporary solution like that, but this should be better fixed at the component level.

Unfortunately, I can't reproduce the issue in a simple sample application. I can only reproduce at will in Gestinux.
However, I believe that the call stack shows that the calling application is not responsible.
But I don't find anything, by reading the call stack and the source.

Any hints appreciated !


Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #5 on: December 27, 2018, 09:40:26 am »
This is the debuglog  (with debug lines added in Grids.pas before DeleteColRow, and before raising exception).
We see that Rows 2 and 1 are deleted, and then TStringCellEditor.Change INIT text=6,00 is called with wrong coordinates (Row=2).


Code: [Select]
DeleteColRow(IsColumn:=False; index := 2);
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
DeleteColRow(IsColumn:=False; index := 1);
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorPos INIT
Grid.EditorPos END
TStringCellEditor.Change INIT text=6,00
***Index Out of range Cell[Col=1 Row=2]
« Last Edit: December 27, 2018, 10:29:55 am by tintinux »
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Questions about call stack in grids.pas
« Reply #6 on: December 27, 2018, 10:32:34 am »
Are there any event handlers attached to the grid? If yes, remove them and see if the issue still exists.

I'd activate debug information for all used units by adding a sorresponding custom option such as -gw2 to "Additions and overrides" of the project options, set a break point on the line which deletes the row and step through the code and into the LCL units.

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #7 on: December 27, 2018, 11:19:41 am »
Quote
Are there any event handlers attached to the grid?
I have already tried to remove them and the issue still exists.

Quote
I'd activate debug information for all used units by adding a sorresponding custom option such as -gw2 to "Additions and overrides" of the project options, set a break point on the line which deletes the row and step through the code and into the LCL units.
I tried and noticed that
Code: Pascal  [Select][+][-]
  1. EditorMode:=False;
is executed at a time, but it looks like it is not enough.
I suppose there is an message sent before the delete by TStringCellEditor, remaining in queue, and processed after the delete, when the application has created another row 1 and writes something in it.  I don't know how I can catch or purge it...

Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #8 on: December 27, 2018, 11:34:55 am »
This is the log with GridTraceMsg :

Code: [Select]
DoubleClick INIT
GRID: [00000014] W=FFFFFFFFC701182F L=00000000 LM_ERASEBKGND
GRID: [00000014] W=FFFFFFFFC701182F L=00000000 LM_ERASEBKGND
GRID: [0000000F] W=FFFFFFFFC701182F L=013FE1A8 LM_PAINT
DeleteColRow(IsColumn:=False; index := 2);
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
DeleteColRow(IsColumn:=False; index := 1);
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorSetMode=False INIT
Grid.EditorSetMode END
Grid.EditorPos INIT
Grid.EditorPos END
StrCellEditor: [0000B012] W=00000000 L=00000000 CM_TEXTCHANGED
TStringCellEditor.Change INIT text='6,00' FCol=1 FRow=2
StrCellEditor: [0000B037] W=00000000 L=0A1E92E0 CM_BASE + 55
GRID: [0000B037] W=00000000 L=0A1E92E0 CM_BASE + 55
***Index Out of range Cell[Col=1 Row=2]

But it don't help me...
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Questions about call stack in grids.pas
« Reply #9 on: December 27, 2018, 12:06:42 pm »
In the first post of this thread you are talking of a "TGrid" component, but there is not TGrid within the LCL. In your gestinux application, there is a TGGrid. This confuses me...

Please specify the TCustomStringGrid descendant for which the bug happens.

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #10 on: December 27, 2018, 01:00:14 pm »
Ah sorry, I'll modify.
The problem is with TCustomStringGrid.
TGGrid is just a descendant of TCustomStringGrid similar to TStringGrid with some additional properties and methods, and some other not published.

« Last Edit: December 27, 2018, 01:03:28 pm by tintinux »
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: Questions about call stack in grids.pas
« Reply #11 on: December 27, 2018, 09:45:21 pm »
Prior to using the DeleteColRow try doing this
EditorMode := False;
Application.ProcessMessages

The only true wisdom is knowing you know nothing

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #12 on: December 29, 2018, 10:12:45 am »
Thanks, i have already tried that, unsuccesfully.

In the code of TCustomStringGrid and in the log, you can see also that EditorMode := False; is executed, but not with Application.Processmessages.
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: Questions about call stack in grids.pas
« Reply #13 on: December 29, 2018, 02:50:04 pm »
I have tested the TStringGrid many times and have never run into that issue yet. You said the component you
are using is a descendant of the TCustumStringGrid.

 Since we know the TstringGrid at this point seems to work I would suggest there is something going
wrong with the control you are using.

 Is it possible you could experiment with the optimizer level, try another level other than -02 because
I have been seeing some complaints about coding not working properly at that level.

The only true wisdom is knowing you know nothing

tintinux

  • Sr. Member
  • ****
  • Posts: 325
    • Gestinux
Re: Questions about call stack in grids.pas
« Reply #14 on: January 22, 2019, 03:22:29 pm »
Hi

I have submitted a bug with a sample program to reproduce it, using only TStringGrid component.

Best regards
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

 

TinyPortal © 2005-2018