-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Check duplicate issues.
- Checked for duplicates
Description
We are facing a critical backward-compatibility issue when reading ROOT 5 files with ROOT 6, which blocks the migration for the NA61/SHINE experiment.
The problem occurs when deserializing a std::map where the key is an enum defined inside a nested namespace.
This issue appears to be a long-standing problem related to namespace resolution in the I/O, previously tracked in JIRA: ROOT-8398.
In ROOT 5, the type name for the map was stored without the fully-qualified namespace (e.g., map<rec::EId,int>). In ROOT 6, the data member is correctly identified with its full namespace (e.g., map<evt::rec::EId,int>).
This leads to two failure modes:
-
Without any I/O rule: ROOT correctly identifies the mismatch but skips the member, issuing a warning:
Warning in <TStreamerInfo::BuildOld>: Cannot convert evt::Event::fi from type: map<rec::EId,int> to type: map<evt::rec::EId,int>, skip element -
With a
#pragma readrule: Following advice from jira issue, a rule added to the LinkDef.h:#pragma read sourceClass="map<rec::EId,int>" targetClass="map<evt::rec::EId,int>"With this rule, ROOT fails with a fatal error and aborts.
Error Log and Stack Trace:
Error in <GetConvertCollectionReadActionFrom>: UNEXPECTED: newtype == 0
Fatal: 0 violated at line 2782 of `/build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx'
aborting
#0 0x00007fb8500d8fba in wait4 () from /lib64/libc.so.6
#1 0x00007fb85004b7e3 in do_system () from /lib64/libc.so.6
#2 0x00007fb85346df32 in TUnixSystem::Exec (this=0x23ce100, shellcmd=0x4f37430 "/cvmfs/sft.cern.ch/lcg/releases/ROOT/6.30.02-fb5be/x86_64-el9-gcc12-dbg/etc/gdb-backtrace.sh 2381395 1>&2") at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/unix/src/TUnixSystem.cxx:2120
#3 0x00007fb85346e7d3 in TUnixSystem::StackTrace (this=0x23ce100) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/unix/src/TUnixSystem.cxx:2411
#4 0x00007fb8532fe716 in DefaultErrorHandler (level=6000, abort_bool=true, location=0x7fb852eb1094 "", msg=0x4f36fc0 "0 violated at line 2782 of `/build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx'") at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/base/src/TErrorDefaultHandler.cxx:177
#5 0x00007fb8533dbec5 in ErrorHandler(Int_t, const char *, const char *, typedef __va_list_tag __va_list_tag *) (level=6000, location=0x7fb852eb1094 "", fmt=0x7fb85363f0f8 "%s violated at line %d of `%s'", ap=0x7ffd6e5a9888) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/foundation/src/TError.cxx:150
#6 0x00007fb8533dc3f6 in Fatal (location=0x7fb852eb1094 "", fmt=0x7fb85363f0f8 "%s violated at line %d of `%s'") at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/foundation/src/TError.cxx:248
#7 0x00007fb852cf5632 in GetConvertCollectionReadActionFrom<TStreamerInfoActions::AssociativeLooper, int> (newtype=0, conf=0x4f366c0) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx:2782
#8 0x00007fb852cea889 in GetConvertCollectionReadAction<TStreamerInfoActions::AssociativeLooper> (oldtype=3, newtype=0, conf=0x4f366c0) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx:2800
#9 0x00007fb852ce4f1c in TStreamerInfo::AddReadAction (this=0x4764990, readSequence=0x4f352e0, i=0, compinfo=0x4ee7038) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx:3355
#10 0x00007fb852ce3944 in TStreamerInfo::Compile (this=0x4764990) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfoActions.cxx:3221
#11 0x00007fb852ccc058 in TStreamerInfo::BuildOld (this=0x4764990) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/io/io/src/TStreamerInfo.cxx:2603
#12 0x00007fb8533f8b5c in TClass::GetStreamerInfoImpl (this=0x472c040, version=1, silent=false) at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.30.02/src/ROOT/6.30.02/core/meta/src/TClass.cxx:4676
...
Reproducer
Here is a minimal working example that demonstrates the crash: test_mapenum.tar.gz
- Data Model (e.g.,
Event.h)
Note theenum EIdinside the nestedevt::recnamespace.
#include <Rtypes.h>
#include <map>
#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 0, 0)
#define VER 2
#else
#define VER 1
#endif
namespace evt {
namespace rec {
enum EId { e1, e2 };
}
class Event {
public:
void Make(rec::EId id, int v) { fi[id] = v; }
int& Get(rec::EId id) { return fi[id]; }
private:
std::map<rec::EId, int> fi;
ClassDefNV(Event, VER);
};
}- LinkDef (e.g.,
EventLinkDef.h)**
This includes the#pragma readhint that triggers the fatal error.
//Fixed in ROOT5
#pragma link C++ namespace evt;
#pragma link C++ namespace evt::rec;
#pragma link C++ class evt::Event+;
#ifdef __CLING__
//ROOT6 only
#pragma link C++ enum evt::rec::EId;
#pragma link C++ class map<evt::rec::EId,int>+;
#pragma link C++ class pair<evt::rec::EId,int>+;
#pragma read sourceClass="map<rec::EId,int>" targetClass="map<evt::rec::EId,int>"`
#endif- Steps
- Compile the dictionary and code with ROOT 5.34 and write a file containing an
evt::Eventobject. - Compile the same dictionary and code with ROOT 6 (e.g., 6.30.02).
- Attempt to read the ROOT 5 file using the ROOT 6 build.
ROOT version
6.30.02 (from LCG 105), also observed in 6.28 (LCG 104 gcc 12) 6.36 (LCG 108 gcc 15)
ROOT 5.34/39 (heads/v5-34-00-patches@v5-34-38-1-g507abd2, Nov 16 2023)
Installation method
LCG_105 lxplus.cern.ch
Operating system
AlmaLinux9
Additional context
This namespace resolution issue is not limited to std::map with enum keys. We see the exact same type of warning (skipping the element) for non-STL templates that use types from nested namespaces with io rule, e.g.:
Warning in <TStreamerInfo::BuildOld>: Cannot convert evt::RecEvent::fMainVertexIndex from type: evt::Index<rec::Vertex> to type: evt::Index<evt::rec::Vertex>, skip element
We experience this fatal error error for the map of enum to template classes, e.g.
map<rec::VertexConst::EType,Index<rec::Vertex> > failed to read to map<evt::rec::VertexConst::EType,evt::Index<evt:rec::Vertex>>.