0

I have a data module which I can not free (funny as it might sound). Whether I try to destroy it manually, or let another component (even Application) do it for me, I get an AV with this stack trace:

exception class   : EAccessViolation
exception message : Access violation at address 0048FC2B in module 'Instruments.exe'. Read of address 80808088.

main thread ($1e28):
0048fc2b Instruments.exe System.Classes    TComponent.RemoveNotification
00408a01 Instruments.exe System         57 @Halt0
00ac86f0 Instruments.exe Instruments    82 initialization

This data module contains a bunch of TADOxxx components, plus two TJvDataSource, one TApplicationEvents, one TClientDataSet, and one TJvAppDBStorage. Its code contains nothing more than opening the ADO connection, writing a few records to a table, running a few queries, etc. (nothing unusual). It doesn't own any other components besides what I mentioned above. I'm puzzled as to where does this bogus call to RemoveNotificaion() originate from. Any ideas?

UPDATE

After removing the TJvAppDBStorage, I can destroy the data module. Here's the component's properties:

object AppStorage: TJvAppDBStorage
  StorageOptions.BooleanStringTrueValues = 'TRUE, YES, Y'
  StorageOptions.BooleanStringFalseValues = 'FALSE, NO, N'
  DataSource = dsConfiguration
  KeyField = 'Key'
  SectionField = 'Section'
  SubStorages = <>
  ValueField = 'Value'
  Left = 272
  Top = 304
end

Has anyone ever used JvAppDBStorage? Is this its normal and expected behavior?

iMan Biglari
  • 4,674
  • 1
  • 38
  • 83
  • I think `Application` would be a better owner. That said, why not carry on passing `nil` and instead call `Free` on the data module yourself. If you want help debugging the AV, give more information. Provide exact error message, code where it is raised, and a call stack. – David Heffernan Mar 18 '13 at 12:25
  • @DavidHeffernan updated the question... As the stack trace shows, the exception is not raised in my code. – iMan Biglari Mar 18 '13 at 12:41
  • Yeah, that's to be expected. Where do you create your data module? In your .dpr file? If so then I would suggest that you call `Free` on it after `Application.Run` returns. And don't make it owned by the main form. So, carry on passing `nil` as the owner. If that fails then we at least have more control over when the destructor is invoked. And it will be easier to debug. – David Heffernan Mar 18 '13 at 12:49
  • @DavidHeffernan I'm creating the data module in `OnCreate()` of my main form. When I pass `nil` as `Owner`, I free it in `OnDestroy()` of the main form. – iMan Biglari Mar 18 '13 at 12:52
  • If you free it in `OnDestroy` then there should be no leaks. Changing `Owner` is not going to help you. – David Heffernan Mar 18 '13 at 12:55
  • @DavidHeffernan That's exactly what I don't understand. I have five data modules, of which four are behaving. This one doesn't like to be released. :-( It owns one `TADOConnection`, four `TADOQuery`, one `TApplicationEvents`, one `TClientDataset`, two `TJvDataSource`, one `TJvAppDBStorage`, and one `TADOCommand` components on in, and I'm not creating any components in its code. I'm beginning to suspect Jv components... – iMan Biglari Mar 18 '13 at 13:03
  • Well, changing `Owner` is going to do nothing. If you are already calling the destructor in the main form's `OnDestroy`, then there should be no leak. You need to debug the leak itself. Your proposed solution is not a real solution. – David Heffernan Mar 18 '13 at 13:04
  • If you have 4 other datamodules that are behaving, have you tried just rebguilding it step by step to find the culprit? – Pieter B Mar 18 '13 at 13:14
  • @PieterB I'm in the process of doing that exactly. Removing components one by one, and running the application – iMan Biglari Mar 18 '13 at 13:15
  • @DavidHeffernan I rephrased my question. – iMan Biglari Mar 18 '13 at 13:17

1 Answers1

2

I've no experience with JvAppDBStorage but I can make a guess as to what is happening.

This component stores settings to a database, as specified by the DataSource property of the JvAppDBStorage instance. In your case that is dsConfiguration. So, for this all to work you need for dsConfiguration to be available whenever AppStorage reads and writes settings. I'll bet that dsConfiguration has already been destroyed when AppStorage attempts to store to it. I expect that happens when AppStorage is freed. So the explanation for the problem is that dsConfiguration is freed before AppStorage.

The solution will be to make sure that dsConfiguration is still alive when AppStorage is freed.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490