Skip to content

Fatal crash (UNEXPECTED: newtype == 0) reading map with nested namespace enum key using #pragma read #20279

@yebondar

Description

@yebondar

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:

  1. 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
    
  2. With a #pragma read rule: 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

  1. Data Model (e.g., Event.h)
    Note the enum EId inside the nested evt::rec namespace.
#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);
  };
}
  1. LinkDef (e.g., EventLinkDef.h)**
    This includes the #pragma read hint 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
  1. Steps
  • Compile the dictionary and code with ROOT 5.34 and write a file containing an evt::Event object.
  • 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>>.

Metadata

Metadata

Assignees

Labels

JIRAbugexperimentAffects an experiment / reported by its software & computimng expertsin:I/O

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions