RE: Problem with writing my own object to TTree

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Sun, 02 Dec 2007 12:34:42 -0600


Hi Tobias,  

You code looks correct and I can not reproduce the problem with root 5.17/04 and up. Could you
try a newer version of ROOT?  

Also I noted that your makefile incorrect link twice against all the .o files
(once in the library, directly in the executable).  

Cheers,
Philippe


From: owner-roottalk_at_root.cern.ch [mailto:owner-roottalk_at_root.cern.ch] On Behalf Of Tobias Raufer
Sent: Sunday, December 02, 2007 6:43 AM
To: roottalk_at_cern.ch
Subject: [ROOT] Problem with writing my own object to TTree

Dear ROOTTalk,

I seem to have a problem with writing my own object to a TTree. First of all, here is the system info:

Mac OS X 10.4.11 on MacBookPro (Intel)
i686-apple-darwin8-g++-4.0.1 (GCC) 4.0.1 root version 5.14/00c

I am attaching some test code reproducing the problem as a (very small) tarball, but here is a short description what I am trying to do: I have two classes, record.h and channel.h, both of which inherit from TObject. I generate the dictionary using rootcint. The class channel.h has an array of doubles as its only data member, and the class record.h has a TClonesArray of channel objects in it. I create a shared library and an executable (see Makefile in the tarball).

The main method looks like this:

int main() {

   TFile file("test.root","RECREATE");
   TTree tree("mytree","mytree");

   record* rec = 0;

   tree.Branch("record branch","record", &rec, 32000, 1);

   for (UInt_t i=0; i<5; ++i)

     rec = new record();
     tree.Fill();

   file.Write();
   return 0;
}

Unfortunately, the program crashes with a bus error. The error occurs at the tree.Fill() line. The back trace is:

#0 0x90029f07 in wait4 ()
#1 0x9004723b in system ()
#2 0x01145677 in TUnixSystem::Exec (this=0xc905af0,
shellcmd=0xc300210 "/usr/bin/gdb -batch -n -x /Users/raufer/T2Ksoft/ nd280rep/ROOT/v5r14p00c/Darwin/gdb-backtrace-script -p 2195 > /tmp/ rootstack.2195 2>&1") at unix/src/TUnixSystem.cxx:1768
#3 0x011459c8 in TUnixSystem::StackTrace (this=0xc905af0) at unix/
src/TUnixSystem.cxx:1856
#4 0x01148835 in TUnixSystem::DispatchSignals (this=0xc905af0,
sig=kSigBus) at unix/src/TUnixSystem.cxx:936
#5 0x011489fd in SigHandler (sig=kSigBus) at unix/src/
TUnixSystem.cxx:338
#6 0x0114781f in sighandler (sig=10) at unix/src/TUnixSystem.cxx:3142
#7 <signal handler called>
#8 0x010f518e in TBuildRealData::Inspect (this=0xbfffea00,
cl=0xcb59fc0, pname=0xbfffe8ec "", mname=0xd5f30 "*fChannels", add=0xcb44c7c) at meta/src/TClass.cxx:229
#9 0x000d594b in record::ShowMembers ()
#10 0x00004302 in G__testDict_187_0_9 ()
#11 0x03d8a3d7 in Cint::G__CallFunc::Execute (this=0xbfffb8e0,
pobject=0xcb44c70) at cint/src/CallFunc.cxx:409
#12 0x01698e33 in Cint::G__CallFunc::Exec (this=0xbfffb8e0,
pobject=0xcb44c70) at include/CallFunc.h:95
#13 0x010fe161 in TClass::BuildRealData (this=0xcb442d0,
pointer=0xcb44c70) at meta/src/TClass.cxx:1075
#14 0x0718eb4b in TTree::BuildStreamerInfo (this=0xbfffee58,
cl=0xcb442d0, pointer=0xcb44c70) at tree/src/TTree.cxx:1876
#15 0x0718f54a in TTree::Bronch (this=0xbfffee58, name=0x6b90 "record
branch", classname=0x6b88 "record", add=0xbfffefc8, bufsize=32000, splitlevel=1) at tree/src/TTree.cxx:1728
#16 0x0718ea32 in TTree::Branch (this=0xbfffee58, name=0x6b90 "record
branch", classname=0x6b88 "record", addobj=0xbfffefc8, bufsize=32000, splitlevel=1) at tree/src/TTree.cxx:1213
#17 0x0718d183 in TTree::BranchImp (this=0xbfffee58,
branchname=0x6b90 "record branch", classname=0x6b88 "record", ptrClass=0xcb442d0, addobj=0xbfffefc8, bufsize=32000, splitlevel=1) at tree/src/TTree.cxx:933
#18 0x00006faa in TTree::Branch<record> ()
#19 0x00002774 in main ()

My two classes look like this:

#ifndef CHANNEL_H
#define CHANNEL_H

#include "TROOT.h"

class channel : public TObject {

public:

   channel();
   virtual ~channel(){};
   void Reset();

   Double_t gain[23];

   ClassDef(channel, 1)
};

#endif //CHANNEL_H

#ifndef record_H
#define record_H

#include "TClonesArray.h"

#include "channel.h"

class record : public TObject
{
  public:

      record();
      virtual ~record();

      channel* operator[]( UInt_t index){
        return dynamic_cast<channel*>( (*fChannels)[index] );
      };

      channel* GetChannel( UInt_t index){
          return dynamic_cast<channel*>( (*fChannels)[index] );
      };

      ClassDef(record, 1)

  private:
      TClonesArray* fChannels;

};

#endif//~record_H

Can anyone help me with this? I tried a few things, e.g. change the split level of the tree, replace the TClonesArray with a c-style array, change the buffer size, etc. I didn't get anywhere though. Your help would be greatly appreciated.

Thanks much,

        Tobi

---
Tobias Raufer

R1,2.90, RAL           
Chilton, Didcot        
OX11 0QX, UK   
+44 1235 778842
+44 1235 446733  (fax)
t.m.raufer_at_rl.ac.uk
Received on Sun Dec 02 2007 - 19:35:19 CET

This archive was generated by hypermail 2.2.0 : Mon Dec 03 2007 - 17:50:02 CET