Persistent fields issues with TBufDataset
Summary
TBufDataset
does not work correctly when persistent fields are involved. In particular, it crashes when the application is closed.
System Information
- Operating system: Windows 11
- Processor architecture: x86-64
- Compiler version: FPC/main (6ab91262, Sept 18 2023), 32 bit
- Device: Computer
Steps to reproduce
- A
TBufDataset
component is dropped on a Lazarus form. - Two persistent fields are created at designtime by double-clicking on the component icon. Then, "Create Dataset" is executed from the context menu.
- The dataset is linked to a
TDBGrid
via aTDataSource
. - The dataset is opened at runtime (no FileName is specified)
- Dummy data are added at runtime to the dataset by calling
AppendRecord
. - BUT: The DBGrid displays strange values which were not passed to
AppendRecord
. - When the application is terminated an exception occurs: ``Project project1 raised exception class 'External: ACCESS VIOLATION' with message: Access violation reading from address $4C006402. In file 'heap.inc' at line 1127: pmcv^.next_var := pmcv^.freelists^.waitvar;''
Example Project
The project created as described above is attached here:
bufdataset_persistentfields_issues.zip
What is the current bug behavior?
See "Steps to reproduce"
What is the expected (correct) behavior?
Correct values in grid as entered. No crash at end.
Possible fixes
I added a memo to the test application which displays some relevant field information after opening the dataset (the code is included in above demo project). The interesting observation is that FieldNo
is displayed with value 0 - which looks very buggy...
Stepping through the code with the debugger I noticed that BindFields
is not called. Therefore I added BindFields(true)
to TCustomBufDataset.InternalOpen
(see patch), and now the FieldNo
values look correct (1, 2, ...), the entered values appear in the grid, and the crash at the end does not occur any more! The same modification also fixes the similar issue in #39563 (closed).
bufdataset_persistentfields.diff
I am not sure whether I added BindFields
at the correct place, but at least it gives an indication on the cause of this issue.