Reference in child class creates seg fault in TClass::GetCollectionProxy


I’m trying to write a class to a tree that inherits from another class and creates an alias by having a reference:

class A {
   std::vector<class X> fHits;

class B {
   std::vector<class X>& fEvents = fHits;

The code compiles and runs, but the first time I try to write class B to file, I get a segmentation fault in TClass::GetCollectionProxy (line 2819). I don’t have a simple example of this, but if I don’t use a reference but rather have another member called fEvents, the program runs without any problems.

Is there anything special I have to do to get references to work, or is this a feature that doesn’t work with ROOT?



ROOT Version: 6.10/08
Platform: CentOS 6.9
Compiler: g++ 4.9.3

Can you provide a small macro reproducing your problem ?

I will try to replicate the problem. However I’m out of town for a week, so I won’t be able to do that any time soon.

Okay, I’ve managed to get a small program that reproduces the problem (I don’t think this can be done in a macro).
I have attached the relevant files that I could upload, unfortunately I can’t upload the makefile.
LinkDef.h (353 Bytes)
HitClass.h (362 Bytes)
test.cxx (454 Bytes)
BaseClass.h (527 Bytes)
HitClass.cxx (42 Bytes)
DerivedClass.h (876 Bytes)
DerivedClass.cxx (50 Bytes)
BaseClass.cxx (44 Bytes)

When I try to run the compiled ./test program, I get:

Error in <TStreamerSTL::GetSize>: Could not find the TClass for vector<HitClass>&.
This is likely to have been a typedef, if possible please declare it in CINT to work around the issue

 *** Break *** segmentation violation

There was a crash.
This is the entire stack trace of all threads:
#0  0x00007f14bc46782e in waitpid () from /lib64/
#1  0x00007f14bc3f9479 in do_system () from /lib64/
#2  0x00007f14c07c042a in Exec (shellcmd=<optimized out>, this=0x1ad5200) at /opt/cern/root/root-6.10.08/core/unix/src/TUnixSystem.cxx:2118
#3  TUnixSystem::StackTrace (this=0x1ad5200) at /opt/cern/root/root-6.10.08/core/unix/src/TUnixSystem.cxx:2412
#4  0x00007f14c07c28bc in TUnixSystem::DispatchSignals (this=0x1ad5200, sig=kSigSegmentationViolation) at /opt/cern/root/root-6.10.08/core/unix/src/TUnixSystem.cxx:3643
#5  <signal handler called>
#6  0x00007f14c0769e30 in TClass::GetCollectionProxy (this=this
entry=0x0) at /opt/cern/root/root-6.10.08/core/meta/src/TClass.cxx:2822
#7  0x00007f14bff47e67 in TStreamerInfo::AddReadAction (this=this
entry=0x2e3cdf0, readSequence=0x2e3f760, i=i
entry=1, compinfo=0x2e3fde8) at /opt/cern/root/root-6.10.08/io/io/src/TStreamerInfoActions.cxx:2607
#8  0x00007f14bff4a389 in TStreamerInfo::Compile (this=0x2e3cdf0) at /opt/cern/root/root-6.10.08/io/io/src/TStreamerInfoActions.cxx:2461
#9  0x00007f14bff1b241 in TStreamerInfo::Build (this=0x2e3cdf0) at /opt/cern/root/root-6.10.08/io/io/src/TStreamerInfo.cxx:672
#10 0x00007f14c076b770 in TClass::GetStreamerInfo (this=this
entry=0x2dd2760, version=1) at /opt/cern/root/root-6.10.08/core/meta/src/TClass.cxx:4406
#11 0x00007f14bea6af2c in TTree::BuildStreamerInfo (this=this
entry=0x21602e0, cl=cl
entry=0x2dd2760, pointer=pointer
entry=0x2dd2640, canOptimize=false) at /opt/cern/root/root-6.10.08/tree/tree/src/TTree.cxx:2565
#12 0x00007f14bea7ab3a in TTree::BronchExec (this=0x21602e0, name=0x40a3dc "branch", classname=<optimized out>, addr=0x7ffdfa600d88, isptrptr=<optimized out>, bufsize=32000, splitlevel=99) at /opt/cern/root/root-6.10.08/tree/tree/src/TTree.cxx:2381
#13 0x00007f14bea642e8 in TTree::Bronch (this=<optimized out>, name=<optimized out>, classname=<optimized out>, addr=<optimized out>, bufsize=<optimized out>, splitlevel=<optimized out>) at /opt/cern/root/root-6.10.08/tree/tree/src/TTree.cxx:2224
#14 0x0000000000405f62 in Branch<DerivedClass> (splitlevel=99, bufsize=32000, addobj=0x7ffdfa600d88, name=0x40a3dc "branch", this=0x21602e0) at /opt/cern/root/root_v6.10.08/include/TTree.h:333
#15 main () at test.cxx:17

I tried adding std::vector& to the LinkDef.h but that did not solve the problem.
One difference between this crash and the one I wrote about earlier is that the earlier one did not create the error message about Error in <TStreamerSTL::GetSize>: Could not find the TClass for ... and the crash happens on line 2819 of TClass.cxx instead of line 2822 of the same file (my earlier post had a typo in the line number).


This seems to be bug in the TStreamerInfo generation code. Reference can not be stored in a ROOT file and should have been marked as transient implicitly. Try the following work-around (marking it transient explicitly):

std::vector<HitClass>& fDerivedMember = fBaseMember; ///<!  Reference are transient by nature.


That did indeed solve the issue with the segmentation fault. The vectors written are all zero size (unlike for other classes where I don’t use references), but that is most likely a bug in the code.
EDIT: definitely a bug in the code, everything works now!
Thank you Philippe!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.