Dear ROOT community,
I’m on an experiment that uses the root library as a framework for data file I/O (among other things). We have a base class for global tracks that can be used throughout the experiment analysis. However, it has fallen prey to a somewhat suspect programming practice, as I shall now show:
#ifndef RBTRACK_H
#define RBTRACK_H
#include “TObject.h”
#include
class RBTrackPoint;
class RBTrack : public std::vector, public TObject
{
public:
typedef std::vector::iterator iterator;
typedef std::vector::const_iterator const_iterator;
public:
RBTrack();
~RBTrack();
const RBTrackPoint& Point(int i) const;
int FindZ(double z, int& i1, int& i2) const;
int GetXY(double z, double* x, double* y) const;
int GetPatZ(double z, double* pxyz) const;
int Id() const {return fId;}
void SetId(int id) { fId = id;}
private:
int fId;
ClassDef(RBTrack,1) // Track base class
};
#endif // RBTRACK_H
As you may have noticed, this inherits from both a TObject AND an STL vector to a class that also derives from TObject. When the author tries to use this class to read in the object later from a TClonesArray, horrible things happen…
|=======================================================================
evt.Reco()
Error in TStreamerInfo::BuildOld: Could not find STL base class: vector for RBTrack
*** Break *** segmentation violation
Generating stack trace…
/usr/bin/addr2line: edm_dump: No such file or directory
/usr/bin/addr2line: edm_dump: No such file or directory
0x41726ca8 in from /lib/i686/libc.so.6
0x402c7a1b in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x12db from /mipp/root/lib/libCore.so.4.02
0x402acb6d in TClass::Streamer(void*, TBuffer&) + 0x1dd from /mipp/root/lib/libCore.so.4.02
0x402aca21 in TClass::Streamer(void*, TBuffer&) + 0x91 from /mipp/root/lib/libCore.so.4.02
0x401f2d5b in TBuffer::StreamObject(void*, TClass const*) + 0x2b from /mipp/root/lib/libCore.so.4.02
0x402872ae in TEmulatedCollectionProxy::ReadItems(int, TBuffer&) + 0x1ce from /mipp/root/lib/libCore.so.4.02
0x40287bbd in TEmulatedCollectionProxy::Streamer(TBuffer&) + 0xcd from /mipp/root/lib/libCore.so.4.02
0x40284c98 in TCollectionStreamer::Streamer(TBuffer&, void*, int) + 0x48 from /mipp/root/lib/libCore.so.4.02
0x40284e86 in TCollectionClassStreamer::operator()(TBuffer&, void*) + 0x36 from /mipp/root/lib/libCore.so.4.02
0x402acc2c in TClass::Streamer(void*, TBuffer&) + 0x29c from /mipp/root/lib/libCore.so.4.02
0x402aca21 in TClass::Streamer(void*, TBuffer&) + 0x91 from /mipp/root/lib/libCore.so.4.02
0x401f0796 in TBuffer::ReadFastArray(void*, TClass const*, int, TMemberStreamer*) + 0x86 from /mipp/root/lib/libCore.so.4.02
0x402c9def in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x36af from /mipp/root/lib/libCore.so.4.02
0x402c80e5 in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x19a5 from /mipp/root/lib/libCore.so.4.02
0x402c6731 in TStreamerInfo::ReadBufferClones(TBuffer&, TClonesArray*, int, int, int) + 0x61 from /mipp/root/lib/libCore.so.4.02
0x40281820 in TClonesArray::Streamer(TBuffer&) + 0x260 from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x40283e87 in TBuffer& operator>>(TBuffer&, TObject*&) + 0x37 from /mipp/root/lib/libCore.so.4.02
0x40293d36 in TList::Streamer(TBuffer&) + 0x316 from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x401f085b in TBuffer::ReadFastArray(void**, TClass const*, int, bool, TMemberStreamer*) + 0xab from /mipp/root/lib/libCore.so.4.02
0x402c816f in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x1a2f from /mipp/root/lib/libCore.so.4.02
0x402ac59c in TClass::ReadBuffer(TBuffer&, void*) + 0x19c from /mipp/root/lib/libCore.so.4.02
0x4041c931 in TFolder::Streamer(TBuffer&) + 0x3f from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x40283e87 in TBuffer& operator>>(TBuffer&, TObject*&) + 0x37 from /mipp/root/lib/libCore.so.4.02
0x40293d36 in TList::Streamer(TBuffer&) + 0x316 from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x401f085b in TBuffer::ReadFastArray(void**, TClass const*, int, bool, TMemberStreamer*) + 0xab from /mipp/root/lib/libCore.so.4.02
0x402c816f in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x1a2f from /mipp/root/lib/libCore.so.4.02
0x402ac59c in TClass::ReadBuffer(TBuffer&, void*) + 0x19c from /mipp/root/lib/libCore.so.4.02
0x4041c931 in TFolder::Streamer(TBuffer&) + 0x3f from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x40283e87 in TBuffer& operator>>(TBuffer&, TObject*&) + 0x37 from /mipp/root/lib/libCore.so.4.02
0x40293d36 in TList::Streamer(TBuffer&) + 0x316 from /mipp/root/lib/libCore.so.4.02
0x402acaee in TClass::Streamer(void*, TBuffer&) + 0x15e from /mipp/root/lib/libCore.so.4.02
0x401f1f8d in TBuffer::ReadObjectAny(TClass const*) + 0x1cd from /mipp/root/lib/libCore.so.4.02
0x401f085b in TBuffer::ReadFastArray(void**, TClass const*, int, bool, TMemberStreamer*) + 0xab from /mipp/root/lib/libCore.so.4.02
0x402c816f in int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, int, int, int, int) + 0x1a2f from /mipp/root/lib/libCore.so.4.02
0x40fe295e in TBranchElement::ReadLeaves(TBuffer&) + 0x14e from /mipp/root/lib/libTree.so.4.02
0x40fd8127 in TBranch::GetEntry(long long, int) + 0x167 from /mipp/root/lib/libTree.so.4.02
0x40fe1990 in TBranchElement::GetEntry(long long, int) + 0x220 from /mipp/root/lib/libTree.so.4.02
0x40fe19d3 in TBranchElement::GetEntry(long long, int) + 0x263 from /mipp/root/lib/libTree.so.4.02
0x4001ed69 in IoEventHandle::Load(int) const at /mipp/packages/IoModules/HEAD/IoEventHandle.cxx:219 from /mipp/releases/development/lib/Linux2-GCC/libIoModules.so
0x400ca1b7 in EDMEventHandle::Bucket(EDMEventHandle::BranchID_t) const at /home2/jsh/mipprels/EventDataModel/EDMEventHandle.cxx:112 from ./lib/Linux2-GCC/libEventDataModel.so
0x400ca2ff in EDMEventHandle::Reco() at /home2/jsh/mipprels/EventDataModel/EDMEventHandle.cxx:134 from ./lib/Linux2-GCC/libEventDataModel.so
0x0804987a in main + 0x612 from edm_dump
0x41713c57 in __libc_start_main + 0xc7 from /lib/i686/libc.so.6
0x080491a1 in _Unwind_Resume + 0x4d from edm_dump
Aborted
The main thing is that ROOT can’t find the info on the STL vector base class. Why would something like this happen? Do we need to pass extra information to ROOT? Does ROOT need to be rebuilt? Should we throw eggs at the person who tried to double inherit from an STL container?
Many thanks in advance,
Joshua Hendrickson