Problem with TTree::MakeClass

Dear ROOT developers and users,

I am using Version 4.03/02 on Vine Linux 3.1 (based on RedHat).
I got segmentation violation every time I tried to quit ROOT
after creating a class object as follows.
Here, the class Foo is defined in Foo.h and Foo.C,
which were generated from a Tree object with simple structure
by t->MakeClass(“Foo”).
I attached the files.
I would appreciate it if you could tell me what the problem is.

root [0] .L simple_event_dll.so
root [1] TFile f(“junk.root”)
root [2] .ls
TFile** junk.root
TFile* junk.root
KEY: TTree Albero eventi;1 Commento all’albero
root [3] TTree *t = (TTree *) f.Get(“Albero eventi”)
root [4] t->Print()


*Tree :Albero eventi: Commento all’albero *
*Entries : 10 : Total = 7288 bytes File Size = 1487 *

  •    :          : Tree compression factor =   1.00                       *
    

*Branch :event_branch *
*Entries : 10 : BranchElement (see below) *

*Br 0 :fUniqueID : *
*Entries : 10 : Total Size= 712 bytes One basket in memory *
*Baskets : 0 : Basket Size= 16000 bytes Compression= 1.00 *

*Br 1 :fBits : *
*Entries : 10 : Total Size= 688 bytes One basket in memory *
*Baskets : 0 : Basket Size= 16000 bytes Compression= 1.00 *

*Br 2 :event_num : *
*Entries : 10 : Total Size= 712 bytes One basket in memory *
*Baskets : 0 : Basket Size= 16000 bytes Compression= 1.00 *

*Br 3 :hits_num : *
*Entries : 10 : Total Size= 706 bytes One basket in memory *
*Baskets : 0 : Basket Size= 16000 bytes Compression= 1.00 *

*Br 4 :hits : hits[hits_num] *
*Entries : 10 : Total Size= 2592 bytes One basket in memory *
*Baskets : 0 : Basket Size= 16000 bytes Compression= 1.00 *

root [5] t->MakeClass(“Foo”)
Info in TTreePlayer::MakeClass: Files: Foo.h and Foo.C generated from TTree: Albero eventi
(Int_t)0
root [6] .L Foo.C
root [7] Foo x
root [8] x.GetEntry(0)
(Int_t)17
root [9] x.Show()
======> EVENT:0
fUniqueID = 0
fBits = 50331648
event_num = 0
hits_num = 0
root [10] .q

*** Break *** segmentation violation
Generating stack trace…
0x00000000017e22d0 in
Foo.C (1.39 KB)
Foo.h (4.13 KB)

I am sorry. I fogot to attach traceback.
The followings are the output of bt command
when running the above on gdb.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 182936155968 (LWP 31353)]
0x00000000017a6769 in ?? ()
(gdb) bt
#0 0x00000000017a6769 in ?? ()
#1 0x0000002a95969d16 in G__G__Base1_105_2_9 ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#2 0x0000002a95fd35b3 in G__call_cppfunc ()
from /opt/heplib/root/pro/lib/libCint.so.4.02
#3 0x0000002a95fb2b34 in G__interpret_func ()
from /opt/heplib/root/pro/lib/libCint.so.4.02
#4 0x0000002a95f99059 in G__getfunction ()
from /opt/heplib/root/pro/lib/libCint.so.4.02
#5 0x0000002a96000725 in G__destroy_upto ()
from /opt/heplib/root/pro/lib/libCint.so.4.02
#6 0x0000002a960008fc in G__scratch_globals_upto ()
from /opt/heplib/root/pro/lib/libCint.so.4.02
#7 0x0000002a958858d0 in TCint::ResetGlobals ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#8 0x0000002a957de72f in TApplication::ProcessLine ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#9 0x0000002a9729471a in TRint::HandleTermInput ()
from /opt/heplib/root/pro/lib/libRint.so.4.02
#10 0x0000002a972943d7 in TTermInputHandler::Notify ()
from /opt/heplib/root/pro/lib/libRint.so.4.02
#11 0x0000002a97295c9d in TTermInputHandler::ReadNotify ()
from /opt/heplib/root/pro/lib/libRint.so.4.02
#12 0x0000002a9592d22b in TUnixSystem::CheckDescriptors ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#13 0x0000002a9592e12e in TUnixSystem::DispatchOneEvent ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#14 0x0000002a958426a5 in TSystem::InnerLoop ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#15 0x0000002a9584bedd in TSystem::Run ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#16 0x0000002a957dd25f in TApplication::Run ()
from /opt/heplib/root/pro/lib/libCore.so.4.02
#17 0x0000002a97294f46 in TRint::Run ()
from /opt/heplib/root/pro/lib/libRint.so.4.02
#18 0x000000000040120d in main ()


Kame

Hi!
I can’t reproduce your problem without simple_event_dll.so
Just guess: you probably have a problem in destructor of “simple event”, so could you try to create an object of class Foo on the heap (use Foo *x = new Foo instead of Foo x)? Does it help?

Hi Konstantin,
thank you for your reply.

I found that ROOT exits normaly when Foo object is created on Heap by
Foo *x = new Foo;
like you told me.
I attached an archive which contains simple_event.h, simple_event.cxx,
provaLinkDef.h, and the main program, build_simple_root.cxx.
The shared library simple_event_dll.so and the executable build_simple_root is generated by following commands.

g++ -g -Wall -fPIC root-config --cflags -c simple_event.cxx
rootcint -f simple_event_dict.cxx -c simple_event.h provaLinkDef.h
g++ -g -Wall -fPIC root-config --cflags -c simple_event_dict.cxx
g++ -shared -O simple_event.o simple_event_dict.o -o simple_event_dll.so
g++ -g -Wall -fPIC root-config --cflags -c build_simple_root.cxx
g++ -g -Wall root-config --libs simple_event_dll.so build_simple_root.o -o build_simple_root

The root file junk.root is created by
./build_simple_root junk.root

Actually, I found them in the past posts of this forum
and added ctor and dtor.

I was wondering, on the interpreter , what is the difference between the cases
where an object is created on heap (with “new” operator) and on stack.
Of course, I understand the difference between objects on heap and stack in C++ program.


Kame
simple_event.tar.gz (1.01 KB)

Hi Kame,

You are trying to delete NULL-object in your destructor. Check if the object exists and then delete it:

simple_event::~simple_event() {
 if (hits) delete [] hits;
}

Hi Konstantin,
thank you for the reply.

C++ guarantees that delete against null pointer is safe (nothing happens).
In fact, the situation did not change
although I added the null check to the destructor.


Kame

Hi,
using a debugger would tell you where it goes wrong. I can give you a hint, though: when calling “Foo x”, Foo::Foo(0) is called, which tries to extract the tree from junk.root. If the file doesn’t exist, or the file doesn’t contain the TTree, Foo::Foo’s tree will be 0. In taht case Init(0) is called, which returns as tree==0. Now you call fChain->Show - but fChain was never initialized (not even to 0 - it will have a random value). Lesson: initialize your members properly in every single constructor.
Axel.

Hi Axel,

You mean that the data member fChain of the Foo object does not point any valid Tree object,
and that is the cause of the crash ?
But I do not think that happend here
because the Tree named “Albero eventi” surely exits in the current directory as shown in my first post.
Am I missing something?


Kame

Oops, sorry, I didn’t read your posting properly, and realized only now that the segv happens when exiting root. The problem is that you have a TFile f(“junk.root”), which gets pulled out in Foo::Foo by gROOT->GetListOfFiles()->FindObject(“junk.root”);, and which gets deleted in Foo’s destructor: delete fChain->GetCurrentFile(). But it also gets deleted by TFile f going out of scope (when leaving root), which means you’re trying to deleted the same object. Not good.

Instead of TFile f(“junk.root”) use a pointer: TFile* f=TFile::Open(“junk.root”).
Axel.

Hi Axel,

I finally got it, thanks a lot.
I wasn’t looking at the desctructor.
Your hint also gave me an idea as to the different behavior
between objects on stack and on heap in an interactive ROOT session.

Thank you again.


Kame