StreamerInfo is not stored in TFile with "update" mode


We have an executable which loops over multiple TFiles (each containing 1 object of different classes not known to this application, though the problem is the same if all includes are added) , and for each file

  1. opens it in the "update" mode (w/o explicitly loading the object stored in the file)
  2. writes some simple struct with metadata
  3. closes the file.

Afterwards, in separate processes, these files are read by other executables (Consumers) which include headers for objects inside these files.

The ClassVersion of the content for some of these files is lower than the current ClassVersion used by Consumers. Automatic schema evolution accounts for differences.

The problem appears when two initial files contain objects of the same class (MyClass in the example below) of version A while the Consumer uses higher class version B because:

  1. the 1st updated file happens to have StreamerInfo of its original object together with the StreamerInfo of the added metadata (as shown by gFile->GetStreamerInfoList()->Print() )
  2. the 2nd updated file has StreamerInfo only for added metadata class, reading the object from these files leads to an error.

I am wondering if there is a way to enforce the presence of the original StreamerInfo in the updated file.

The reproducer is attached:

tar xvzf tst.tar.gz ;  cd tst; chmod +x;

It produces (suppressing ACLIC output):

Creating library for MyClass version 1
Storing object of class version 1 in two identical files
Creating library for MyClass version 2
Updating files containing object of old class version 1 (by writing metadata object of unrelated class OtherClass)

Reading 1st (updated) file
Processing testFile.C("outv1.root")...
printing GetStreamerInfoList()->Print() for outv1.root
Collection name='TList', class='TList', size=2
 OBJ: TStreamerInfo	MyClass	
 OBJ: TStreamerInfo	OtherClass	

Reading 2nd (updated) file
Processing testFile.C("outv2.root")...
Error in <TBufferFile::CheckByteCount>: object of class MyClass read too many bytes: 12 instead of 6
Warning in <TBufferFile::CheckByteCount>: MyClass::Streamer() not in sync with data on file outv2.root, fix Streamer()
printing GetStreamerInfoList()->Print() for outv2.root
Collection name='TList', class='TList', size=1
 OBJ: TStreamerInfo	OtherClass	

tst.tar.gz (1.2 KB)

ROOT Version: 6.28/04
Platform: Ubuntu 22.04
Compiler: gcc (GCC) 12.2.0

Maybe @pcanal can give it a try

The problem was solved by IO: Fix StreamerInfo record write during file update. by pcanal · Pull Request #13842 · root-project/root · GitHub which is available in v6.28/06 and up.

1 Like

Thanks @pcanal !

Will need to bump the root in Alice O2.


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