Yes, this is what I was looking for. So it does look like the initialization of the TClass for TMnemonic is starting as expected but is not completing correctly.
Alongside (in the same directory as) the shared library that contains the code for TMnemonic, do you have a file with a similar name and the suffix: _rdict.pcm?
There are a number of _rdict.pcm files, yes. But there isn’t a single file that corresponds to the library I’m loading as the library is several other libraries (with individual pcm files) linked together.
Also, I just noticed that the sub-library used for the base class has the same name as the one used for the class inheriting from it (and thus the two _rdict.pcm files have the same name even though they are in two different directories). Could this be the issue?
I will try and rename the libraries for the base classes.
where libTFormat.so and TFormatDict_rdict.pcm contain the definitions of the parent class TMnemonic.
The library that I then load which contains the daughter class is GRSIData/lib/libGRSIData.so:
(and thus the two _rdict.pcm files have the same name even though they are in two different directories). Could this be the issue?
Yes, this is most likely the issue.
But there isn’t a single file that corresponds to the library I’m loading as the library is several other libraries (with individual pcm files) linked together.
Fair enough. Did you use the flag:
-multiDict Enable support for multiple pcms in one library
Needs the -s flag. See its documentation.
Seems that it’s not in the call to rootcint/rootcling as that gives me an error
Error: Multidict requested but no target library. Please specify one with the -s argument.
So how do I use this flag correctly?
Currently our makefile uses rootcint/rootcling to generate the dictionary, compiles the dictionary into an object file (.o), which is then used in the linking of the library. Then all the shared libraries are linked together to another shared library which we use. At which stage should the multiDict flag be used?
SysError in <TFile::TFile>: file lib/libGROOT_GROOTDict_rdict.pcm can not be opened (No such file or directory)
I don’t know where rootcling got the weird name from (there will be a lib/GROOTDict_rdict.pcm after the build is done). But isn’t the _rdict.pcm file generated by this call to rootcling?
EDIT: Okay, from rootcling -h I see that using -multiDict causes the -s flag to influence the name of the created pcm to be libTARGETLIBRARY_DICTIONARY_rdict.pcm (and in this case TARGETLIBRARY and DICTIONARY are both GROOT). So I changed the -s flag to be just -s libGROOT.so (without leading lib/), and the error is gone.
So after the program and the library were completely re-compiled I tried again, and I get the same crash and the stack trace is the same (memory addresses are different of course).
works and creates (amongst others) the files .build/libraries/GROOT/GROOT_GROOTDict_rdict.pcm and libGROOT.rootmap. Not sure why the latter is created in the main directory (where make is executed), maybe because I didn’t specify its path using the -rml flag?
Okay, using -rmf solved that issue. I now have both the .pcm and .rootmap file created in the same directory.
Currently our makefile is set up to copy all .pcm files into the same lib/ directory where all the shared object libraries of the program are. Should the .rootmap files also be copied into this directory?
EDIT: I tried copying the .rootmap files into the two different lib directories (the one for the main program and the one for the library that gets loaded), and I still get the same crash.
Where did you get this information from? An old file? Because I had to rename the TGRSIFormat library to TFormat. And I just double checked using a grep for TGRSIFormat that this name now only appears in the sub-directory with the library that gets loaded later.
humm … maybe the code moved … I got this line number from the stack your provided by the use of SetClassSize:
#0 ROOT::TGenericClassInfo::GetClass (this=0x7ffff5f62140 <ROOT::GenerateInitInstanceLocal(TMnemonic const*)::instance>) at /opt/cern/root/root-6.14.04/core/meta/src/TGenericClassInfo.cxx:280
#1 0x00007ffff5d2f856 in TMnemonic::Class () at .build/libraries/TGRSIFormat/TGRSIFormatDict.cxx:946
#2 0x00007ffff5cd4471 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at libraries/TGRSIFormat/TChannel.cxx:33
#3 _GLOBAL__sub_I_TChannel.cxx(void) () at libraries/TGRSIFormat/TChannel.cxx:1410
#4 0x00007ffff7deab03 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#5 0x00007ffff7ddc06a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000002 in ?? ()
#7 0x00007fffffffe256 in ?? ()
#8 0x00007fffffffe290 in ?? ()
#9 0x0000000000000000 in ?? ()
or maybe I am looking for what on line TGRSIFormat/TChannel.cxx:33 (stack #2).
#0 ROOT::TGenericClassInfo::GetClass (this=0x7ffff78d0140 <ROOT::GenerateInitInstanceLocal(TMnemonic const*)::instance>) at /opt/cern/root/root-6.14.04/core/meta/src/TGenericClassInfo.cxx:280
#1 0x00007ffff769d856 in TMnemonic::Class () at .build/libraries/TFormat/TFormatDict.cxx:946
#2 0x00007ffff7642471 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at libraries/TFormat/TChannel.cxx:33
#3 _GLOBAL__sub_I_TChannel.cxx(void) () at libraries/TFormat/TChannel.cxx:1410
#4 0x00007ffff7deab03 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#5 0x00007ffff7ddc06a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000002 in ?? ()
#7 0x00007fffffffe256 in ?? ()
#8 0x00007fffffffe290 in ?? ()
#9 0x0000000000000000 in ?? ()
okay. That makes much more sense and indicate that creating a TClass from a rootpcm is not working correctly during library setup. You can work-around the problem by using: