Incorrect behaviour in TOracleDataSet destructor.

AndreyB

Member²
In destructor the last line of code calls inherited Destroy which in turn tries to call Close and InternalClose accordingly. In your overrided Internalclose you try to use internal fields which you just destroyed in the destructor (before inherited one). The easiest solution just to call Close at the begining of Destroy in that case descendant Close will not call InternalClose again from it's own Destructor.
 
What is the problem? Everything seems to work just fine.

------------------
Marco Kalter
Allround Automations
 
The problem is that its only seems like works fine.

This is what happened. I had a problem in my application during terminating it. The Delphi just hanged up with VCL50.bpl error. It turned out that the problem was with incompatibility between oratrace8 and integrated debugger. But meanwhile I was desperately trying to find the problem in my code. I included debug information in DOA package and compiled in the project VCL source.
In my application I dynamically create a lot of datasets in multiple threads and sometimes I've had an exception in TList. When I traced it down I saw the next stack

TOracleDataset.InternalClose;
TDataSet.Destroy;
TOracleDataSet.Destroy;

The problem was that I didn't close my datasets before destroing them (I guess I didn't have to) and in your TOracleDataSet.Destructor your first destroy your own private fields (like FDetails for instance) then you call inhereted Destroy (TDataSet) which call Close first that automatically lead to call of TOracleDataSet.InternalClose where you in EnableMasterFields refer to just destroyed FDetails (if check more carefully you refer to some others just destroyed fields). Of course referral to the component which was just destroyed not always lead to the exception, only if it's memory was occupied by something else. But this is what happened in my case (I believe because of threads). When I looked at implementation of TBDEDataSet and TIBDataSet they always call in their destructors inhereted destructor first and only then do own clean up. But in you case it's not gonna work because you created some internal fields with TOracleDataSet as an owner and as a result they are destroyed in inherited TComponent.Destructor before your clean up in your own destroy. So the easiest way to fix that problem, I've found, just to call Close at the beginning of TOracleDataSet.Destroy, that way InternalClose will not be called from the TDataSet.
 
Excuse me, guys. Are you gonna fix this or not? It's actually a very big problem, may be hidden for some apps for a while. And I believe this is one of the problem of hard to catch unstability when you use DOA in multiple threads.
 
I have to agree. This should be looked into, I'm not sure if I fully understand what's going on here, but I have dealt with destructor problems before (in the VCL) and they're very difficult to trace or reproduce. Especially when you're not too familiar with the code involved.
 
It is looked into, and it is fixed. We will have a 3.4.3 patch release available shortly.

------------------
Marco Kalter
Allround Automations
 
Back
Top