Warning in <TClass::TClass>: no dictionary for class

Hello,

Can anybody tell me why this message appears in ROOT v5.34/22 (and also before) when I load
my .so containing ~100 classes:

(ROOT 5.34/22)
root [0] gSystem->Load("libKVMultiDet")
Warning in <TClass::TClass>: no dictionary for class KVSeqCollection is available

You can find the class documentation here: http://indra.in2p3.fr/KaliVedaDoc/1.9.2/KVSeqCollection.html

I cannot see what is different about this class compared to all the others in the .so
which don’t present any problem. Although it has not stopped me working with 5.34,
it seems to be related to the problem I have recently encountered with 6.02,
which makes any TClass::GetClass(“class”) with a class deriving from or containing a KVSeqCollection-
derived class end in segmentation violation at line 253 of TProtoClass.cxx:

TRealData* TProtoClass::TProtoRealData::CreateRealData(TClass* dmClass, TClass* parent) const
{
   // Create a TRealData from this, with its data member coming from dmClass.
   TDataMember* dm = (TDataMember*)dmClass->GetListOfDataMembers()->FindObject(GetName());

The problem is that, when dmClass is the TClass for KVSeqCollection, dmClass->GetListOfDataMembers()
returns 0x0 unless things are initialised in just the right particular order:

If I explicitly load the .so it doesn’t work:

(ROOT 6.02)
root [0] gSystem->Load("libKVMultiDet")
(int) 0
root [1] KVSeqCollection::Class()->GetListOfDataMembers()
(class TList *) 0x0

If I let cling autoload the .so in this way, it doesn’t work:

root [0] KVSeqCollection::Class()->GetListOfDataMembers()
(class TList *) 0x0

If I let cling autoload the .so in another way, it works (and this is the only case which works):

root [0] TClass::GetClass("KVSeqCollection")->GetListOfDataMembers()
(class TList *) 0x3200650

You might think that a “solution” (kludge) would be to add a ‘TClass::GetClass(“KVSeqCollection”)’ somewhere in the code before any TClass::New or other trickery gets used: but no, if I put it in
one of my classes it does no good! It has to be at the interpreter command line. I have no idea
what is wrong with my class.

Cheers,
John

Hi John,

do you think it’s possible to have a reproducer for this issue in form of a headerfile, a linkdef/selection xml and the commands you use to create the shared library?

Best,
Danilo

Hi Danilo
I’m having trouble making a stand-alone example for this. I copied the whole build system
and removed everything but the KVSeqCollection base class, generated the .so and guess what:
no problems :laughing:
i.e. the KVSeqCollection::Class()->GetListOfDataMembers() always gives a valid list.
The only difference I could find in the dictionary code between this and the full library was

(KVSeqCollection compiled on its own):
class __attribute__((annotate(R"ATTRDUMP(KaliVeda extensions to ROOT collections)ATTRDUMP"))) __attribute__((annotate("$clingAutoload$base/KVSeqCollection.h")))  KVSeqCollection;

(KVSeqCollection compiled with all the other classes):
class __attribute__((annotate(R"ATTRDUMP(KaliVeda extensions to ROOT collections)ATTRDUMP"))) __attribute__((annotate("$clingAutoload$base/KVUniqueNameList.h")))  KVSeqCollection;

I don’t know what this does, but there seems to be some interference between classes:
KVUniqueNameList derives from KVSeqCollection, but not directly; there is an intermediate
class KVHashList (KVSeqCollection <- KVHashList <- KVUniqueNameList)
So I added the two derived classes to my stand alone example, now the ‘class__attribute’ is the same
as for the real library, but still the problem is not reproduced.

The dictionary is generated with

rootcling -v -f KVMultiDetbaseDict.cpp -rml libKVMultiDet.so -rmf libKVMultiDetbase.rootmap -c -p -Ibase -DWITH_OPENGL -I/home/john/work/kaliveda_debug/ROOT6/KVSeqCollection_example -I/home/john/work/kaliveda_debug/ROOT6/KVSeqCollection_example/build/include base/KVUniqueNameList.h base/KVSeqCollection.h base/KVHashList.h base/KVMultiDetbaseLinkDef.h

My (reduced) link def is

#ifdef __CINT__
#include "RVersion.h"
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclass;
#pragma link C++ nestedtypedef;
#pragma extra_include "Rtypes.h";
#pragma link C++ class KVSeqCollection-;
#pragma link C++ class KVHashList+;
#pragma link C++ class KVUniqueNameList+;
#endif

N.B. the order of the 3 classes is the same as in the real linkdef.

Dictionary compilation:

g++ -Wall -Wextra -Werror=overloaded-virtual -Werror=non-virtual-dtor -Werror=type-limits -Werror=sign-compare -Werror=unused-but-set-variable -Wno-format-security -Wno-unused-parameter -Wunused-but-set-parameter -Wunused-variable -Wall -fPIC -pthread -std=c++11 -Wno-deprecated-declarations -m64 -I/home/john/software/build/root-v6-02-00/include  -Ibase -DWITH_OPENGL -I/home/john/work/kaliveda_debug/ROOT6/KVSeqCollection_example -I/home/john/work/kaliveda_debug/ROOT6/KVSeqCollection_example/build/include -c -o KVMultiDetbaseDict.o KVMultiDetbaseDict.cpp

Shared library generation:

c++ -shared -m64 -O3  -Wl,--no-as-needed -Wl,--no-undefined base/KVUniqueNameList.o base/KVSeqCollection.o base/KVHashList.o KVMultiDetbaseDict.o -L/home/john/software/build/root-v6-02-00/lib -lGui -lCore -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic  -L/home/john/software/build/root-v6-02-00/lib -lRGL -L/home/john/software/build/root-v6-02-00/lib -lGeom -L/home/john/software/build/root-v6-02-00/lib -lSpectrum -L/home/john/software/build/root-v6-02-00/lib -lProofPlayer -lProof -o  libKVMultiDet.so 

By the way, since updating v6-02-00-branches, I no longer have a segmentation violation in TProtoClass,
rather some new error messages appear:

Error in <CreateRealData>: Cannot find data member # 0 of class KVSeqCollection for parent KVUniqueNameList!
Error in <TProtoClass::FindDataMember>: data member with index 1 is not found in class KVSeqCollection
Error in <CreateRealData>: Cannot find data member # 1 of class KVSeqCollection for parent KVUniqueNameList!
Error in <TProtoClass::FindDataMember>: data member with index 0 is not found in class KVSeqCollection
Error in <CreateRealData>: Cannot find data member # 0 of class KVSeqCollection for parent KVHashList!
Error in <TProtoClass::FindDataMember>: data member with index 1 is not found in class KVSeqCollection
Error in <CreateRealData>: Cannot find data member # 1 of class KVSeqCollection for parent KVHashList!

I am really stuck now. As I said at the beginning, it might be easier to debug with 5.34, i.e. if I could
only understand why CINT/rootcint would claim that a dictionary is not available for a class when
it is not the case?

Thanks for your help

Forgot to say: this is the output when things are working

root [0] KVSeqCollection::Class()->GetListOfDataMembers()->ls()
OBJ: TListOfDataMembers	TListOfDataMembers	List of TDataMembers for a class : 0
 OBJ: TDataMember	fQObject	 : 0 at: 0x194aeb0
 OBJ: TDataMember	kSignals	 : 0 at: 0x194e4c0
 OBJ: TDataMember	kCleanup	 : 0 at: 0x194e660
 OBJ: TDataMember	fSCCounter	counter used to give unique names to all lists : 0 at: 0x194e860
 OBJ: TDataMember	fCollection	Pointer to embedded ROOT collection : 0 at: 0x194ec10
 OBJ: TDataMember	fgIsA	 : 0 at: 0x194ed20

so you can see the data members #0 and #1 referred to in the error messages are a TQObject
(from use of RQ_OBJECT macro) and a member of an anonymous enum
(see indra.in2p3.fr/KaliVedaDoc/1.9.2 … ion.h.html)

Hi John,

when looking at the error generated by protoclasses, it really seems that something not clear is going on.
How can I download the KaliVeda version you are using? Can you give me a hint on how to build it against ROOT6? At that point I must be able to reproduce the errors you reported.

Cheers,
Danilo

Hi Danilo
Thankyou very much for your patience and help!
You can download the same version of the code as I am using from Launchpad where
it is stored as a bazaar branch (see https://code.launchpad.net/~kaliveda-dev/kaliveda/1.9):

You will find full instructions for building & installing in the file kaliveda.bzr/INSTALL.
Here is the short version:
Before building, create the directory where you want to install the libraries etc.
and set the environment variable KVROOT with the full path to this installation directory.
Add $KVROOT/lib to $LD_LIBRARY_PATH.
(To gain some time in the build, edit the main Makefile and replace the line#147:

all : fitltg-0.1/configure .init $(KV_CONFIG__H) KVVersion.h $(BZR_INFOS) ltgfit $(RGTAPE) MultiDet Indra $(INDRAVAMOS) FAZIA install analysis byebye

by

all : fitltg-0.1/configure .init $(KV_CONFIG__H) KVVersion.h $(BZR_INFOS) ltgfit $(RGTAPE) MultiDet install byebye

so that only the main library, libKVMultiDet.so, will be built)
Then build & install by doing

% cd kaliveda.bzr
% make debug=yes

You should then be able to do (in any working directory):

% root -l -n
root [0] KVSeqCollection::Class()->GetListOfDataMembers()
(class TList *) 0x0
root [1] TClass::GetClass("KVSeqCollection")->GetListOfDataMembers()
(class TList *) 0x0
root [2] .q
% root -l -n
root [0] TClass::GetClass("KVSeqCollection")->GetListOfDataMembers()
(class TList *) 0x2448990
root [1] TClass::GetClass("KVHashList")
(class TClass *) 0x28bf4a0
root [2] .q
% root -l -n
root [0] TClass::GetClass("KVHashList")
Error in <TProtoClass::FindDataMember>: data member with index 0 is not found in class KVSeqCollection
Error in <CreateRealData>: Cannot find data member # 0 of class KVSeqCollection for parent KVHashList!
Error in <TProtoClass::FindDataMember>: data member with index 1 is not found in class KVSeqCollection
Error in <CreateRealData>: Cannot find data member # 1 of class KVSeqCollection for parent KVHashList!
(class TClass *) 0x240ce50
root [1] TClass::GetClass("KVSeqCollection")->GetListOfDataMembers()
(class TList *) 0x0

Hi John,

I could download the sources but during the make I got:

configure: error: cannot find install-sh, install.sh, or shtool in "." "./.." "./../.."

what am I missing?

D

Hi Danilo
You must have all the GNU autotools installed - automake, autoconf, autoreconf, libtool, etc. etc.
After an initial build failure due to missing tools it probably won’t work after installing the missing stuff,
so the best is probably to delete the directory you checked out from launchpad and start again… :frowning:
If you already have everything installed, then it’s a different problem #-o
Hope this helps
John

Hello John,

I am sure I have the whole pack of autotools on my system as well as a fortran compiler (f77).
Now I am getting this other problem:

checking for Fortran 77 libraries of ... 
checking for dummy main to link with Fortran 77 libraries... none
checking for Fortran 77 name-mangling scheme... configure: error: in `/home/dpiparo/KaliVeda/kaliveda.bzr/fitltg-0.1':
configure: error: cannot compile a simple Fortran program
See `config.log' for more details
make: *** [.init] Error 1

I attach the config.log.
This is my version of f77:

f77 -v
/usr/bin/f77: fort77 Version 1.15
/usr/bin/f77: No input files specified

Still no chance to get a stand alone reproducer? :frowning:

Best,
Danilo
config.log.gz (6.48 KB)