ROOT destroys my TFile before my object's destructor

Hi.

How do I work around the following problem?

I have an object that owns a pointer to a TFile. When my destructor is called, I attempt to close the file and delete the memory. This works fine when I use my object in a compiles program. But I get a crash when I’m using ROOT’s CINT. This is, I believe, because ROOT destroys my TFile before my object’s destructor is called.

I’ve attached an example class.

Here’s the use and crash:

root [0] TFile ff("test.root","recreate")
root [1] ff.Close()
root [2] .L KTestFile.cxx++
Info in <TUnixSystem::ACLiC>: creating shared library /Users/adam/test/kds/KTestFile_cxx.so
root [3] KTestFile f("test.root")
root [4] .q

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================

Thread 1 (process 58395):
#0  0x00007fff955b2168 in wait4 ()
#1  0x00007fff92f215f5 in system ()
#2  0x00000001000cc16c in TUnixSystem::StackTrace ()
#3  0x00000001000cf02a in TUnixSystem::DispatchSignals ()
#4  <signal handler called>
#5  0x00000001012dacd6 in KTestFile::Close ()
#6  0x00000001012d9ced in KTestFile::~KTestFile ()
#7  0x00000001012da933 in G__KTestFile_cxx_ACLiC_dict_2950_0_5 ()
#8  0x00000001008c6ea6 in Cint::G__ExceptionWrapper ()
#9  0x000000010098fb5d in G__execute_call ()
#10 0x00000001009901ca in G__call_cppfunc ()
#11 0x000000010094e18a in G__interpret_func ()
#12 0x000000010093c9a4 in G__getfunction ()
#13 0x00000001009e988e in G__destroy_upto ()
#14 0x00000001009e9c44 in G__scratch_globals_upto ()
#15 0x000000010009b6c0 in TCint::ResetGlobals ()
#16 0x00000001000cca8f in TUnixSystem::Exit ()
#17 0x0000000100008e2b in TApplication::ProcessLine ()
#18 0x000000010123cde6 in TRint::HandleTermInput ()
#19 0x000000010123c8c5 in TTermInputHandler::Notify ()
#20 0x000000010123e6ad in TTermInputHandler::ReadNotify ()
#21 0x00000001000ce097 in TUnixSystem::CheckDescriptors ()
#22 0x00000001000ce99b in TUnixSystem::DispatchOneEvent ()
#23 0x000000010005775c in TSystem::InnerLoop ()
#24 0x000000010006227e in TSystem::Run ()
#25 0x0000000100005ecb in TApplication::Run ()
#26 0x000000010123da0f in TRint::Run ()
#27 0x00000001000009ff in main ()
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00000001012dacd6 in KTestFile::Close ()
#6  0x00000001012d9ced in KTestFile::~KTestFile ()
===========================================================

thanks for your help.
Adam
KTestFile.h (348 Bytes)
KTestFile.cxx (798 Bytes)

Hi,

Thank you for reporting this problem, it is fixed by revision 40940 of the trunk.
You can work-around the issue by adding: if (!fFile->TestBit(TObject::kNotDeleted)) { return true; }to KTestFile::Close before the test on IsOpen.

Cheers,
Philippe.

[quote=“pcanal”]Hi,

Thank you for reporting this problem, it is fixed by revision 40940 of the trunk.
You can work-around the issue by adding: if (!fFile->TestBit(TObject::kNotDeleted)) { return true; }to KTestFile::Close before the test on IsOpen.

Cheers,
Philippe.[/quote]

If it was deleted, how can you call any non-static member function with invalid pointer?

[quote]If it was deleted, how can you call any non-static member function with invalid pointer?[/quote]It is a work-around that relies on the fact that TestBit is a non-static member functions and on the fact that in this case the memory were the object was has not yet been reused. You are correct that this is not a long term solution and is not a generic solution (for that only the patch in the repository will help, another alternative would be to register the user object in the list of cleanups in TROOT and implement RecursiveRemove).

Cheers,
Philippe.