Segmentation violation when reading TClonesArray from Tree in root 6 (works root 5)

Dear all.
I am seeking help for a problem I am having troubles to debug.
I am storing into a tree objects from a custom class.

The relevant part is:
class MyObject : public TAGdata {
public:

/*
omissis
*/
ClassDef(MyObject,1)

public:
Short_t nhit; // nhit
TClonesArray* h; // hits
};

such TAGdata is written into a tree. As long as I use root (v. 5.3*) I can create my objects, fill the tree, close the rootfiles and read it back without problems.
When opening the root file I see the relative branches and I can click on them and navigate them (as you can see from the attached picture).


When switching to root 6.07/06 I am able to: compile the code without problems, run it, create the files. The same structure is created and no warning nor error message appears at runtime.



But when I try to access the info by navigating the TBrowser it fails with the following error messages, and I am no longer able to access the leaves.

Warning in TBufferFile::CheckObject: reference to object of unavailable class TClonesArray, offset=262145 pointer will be 0
Error in TBufferFile::CheckByteCount: object of class MyObject read too few bytes: 28 instead of 4277
Error in TExMap::Remove: key 262145 not found at 82

Furthermore if i try to read back the info from the root file I have a segmentation violation (the error message is attached below).

Any help on how to proceed with the debugging would be welcomed. Is any new feature introduced with root 6 that could cause such behavior?
Any documentation that I should have a look at?
Thanks,
Alessio

*** Break *** segmentation violation
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[/Users/Shared/Packages/root/lib/libCling.so] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) /Users/Shared/Packages/root-6.06.94/core/meta/src/TCling.cxx:1862
[/Users/Shared/Packages/root/lib/libCling.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) /Users/Shared/Packages/root-6.06.94/core/meta/src/TCling.cxx:2003
[/Users/Shared/Packages/root/lib/libCling.so] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) /Users/Shared/Packages/root-6.06.94/core/meta/src/TCling.cxx:2840
[/Users/Shared/Packages/root/lib/libCore.so] TApplication::ExecuteFile(char const*, int*, bool) /Users/Shared/Packages/root-6.06.94/core/base/src/TApplication.cxx:1129
[/Users/Shared/Packages/root/lib/libRint.so] TRint::ProcessLineNr(char const*, char const*, int*) /Users/Shared/Packages/root-6.06.94/core/rint/src/TRint.cxx:756
[/Users/Shared/Packages/root/lib/libRint.so] TRint::Run(bool) /Users/Shared/Packages/root-6.06.94/core/rint/src/TRint.cxx:421
[/Users/Shared/Packages/root/bin/root.exe] main /Users/Shared/Packages/root-6.06.94/main/src/rmain.cxx:32
[]


This is *very* suspicious.  TClonesArray is part of the ROOT main libraries and can not (in normal circunstances) be 'unavailable'.

This leads me to believe that the most likely problems is a setup problem (whether ROOT is either not fully build, not fully installed and/or the environment is not set correctly).  There is also a smaller chance that this is due to memory corruption.

Note that you could verified that the file is produced correctly by reading it with ROOT v5.   You also should try to read with the new version a file produced with the old version.

Also try to do the following on the command line:[code]TClonesArray::Class()->GetStreamerInfo()->ls();[/code]

Cheers,
Philippe.

This is very suspicious. TClonesArray is part of the ROOT main libraries and can not (in normal circunstances) be ‘unavailable’.

This leads me to believe that the most likely problems is a setup problem (whether ROOT is either not fully build, not fully installed and/or the environment is not set correctly). There is also a smaller chance that this is due to memory corruption.

Note that you could verified that the file is produced correctly by reading it with ROOT v5. You also should try to read with the new version a file produced with the old version.

Also try to do the following on the command line:TClonesArray::Class()->GetStreamerInfo()->ls();

Cheers,
Philippe.

Thanks for the prompt reply.
I have tried what you suggested: I was able to read without problem with root v6 the file produced with v5 and to navigate it producing the sample plot I attached before.

It’s also true that when I try to read with v5 the files produced with v6 I still find the same problem I found before:
Warning in TBufferFile::CheckObject: reference to object of unavailable class TClonesArray, offset=262145 pointer will be 0
Error in TBufferFile::CheckByteCount: object of class MyObject read too few bytes: 28 instead of 6167
Error in TExMap::Remove: key 262145 not found at 82

So it seems a problem related to how the info is stored in the file and not the root v5 or v6 build/setup.
I have also tried the command suggested on both installations and I got respectively what is attached below.

Cheers,
Alessio

ROOT 5.32/01 (tags/v5-32-01@43181, Feb 29 2012, 16:46:43 on linux)
CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
root [0] TClonesArray::Class()->GetStreamerInfo()->ls();

StreamerInfo for class: TClonesArray, version=4, checksum=0x460cc5b
TObjArray BASE offset= 0 type= 0 An array of objects
i= 0, TObjArray type= 0, offset= 0, len=1, method=0

and


| Welcome to ROOT 6.07/06 root.cern.ch |
| © 1995-2016, The ROOT Team |
| Built for macosx64 |
| From tag v6-07-06, 1 April 2016 |

root [0] TClonesArray::Class()->GetStreamerInfo()->ls();

StreamerInfo for class: TClonesArray, version=4, checksum=0xb6c0ca63
TObjArray BASE offset= 0 type= 0 An array of objects
i= 0, TObjArray type= 0, offset= 0, len=1, method=0

[quote]It’s also true that when I try to read with v5 the files produced with v6 I still find the same problem I found before:[/quote]Fair enough, so the issue is in the writing code. Can you provide this code (or sub-set reproducing the problem)?

Cheers,
Philippe.

The MyObject writing is performed using the attached class.

TAGactTreeWriter.cxx (9.68 KB)
TAGactTreeWriter.hxx (1.96 KB)

The MyObject class is defines as
class MyObject : public TAGdata.

I hope that some hint on what might be wrong in the writing process could be guessed from here. I’ll also try to strip of the minimal part of code that is “self contained” to reproduce the problem [not easy as it is part of a large software project]

thanks again very much for the very kind help and support.

nothing obvious in the code.
Could you send me both a good file and a bad file?
Thanks,
Philippe.

Here are the two root files obtained using v5 and v6.

DecodedMC_v5.root (187 KB)

DecodedMC_v6.root (185 KB)

Cheers,
Alessio

Can I provide any further information to help debugging this problem?

Hi Alessio,

For some reason the v6 producer believe that the class TAGntuMCeve (and maybe more) has a ‘custom streamer’.

In v6, the TTree correctly respect the fact that a class has a custom Streamer and does not allow splitting of a branch if there is one while in v5 if splitting was requested the custom streamer was (incorrectly) ignored.

The consequence of having a custom streamer is that you then must have this custom streamer loaded (i.e. the shared library containing the compiled code) in order to do any reading of the file.

If it is not your intention to have a custom streamer, then we need to find out why v6 believe you have one. First things to look at is the LinkDef file that you are using for the class TAGntuMCeve and see if has a trailing plus or minus sign or nothing.

Cheers,
Philippe.

That was indeed it!!!
I completely forgot to check the LinkDef file…
I was missing a +…
switching to
#pragma link C++ class TAGntuMCeveHit+;
#pragma link C++ class TAGntuMCeve+;
did the trick.

Thank you so much for your kind help and support!!!
Alessio