There seems to be no test/example of ToolHandleArray usage outside of Athena except for one member in GaudiExamples/MyGaudiAlgorithm that isn't used in the corresponding options file. I tried to use it like this:
cmake --build /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt --target all -- [4/6] Generating genConf/GaudiExamples/GaudiExamplesConf.py, genConf/GaudiExamples/__init__.py, genConf/GaudiExamples/GaudiExamples.confdbFAILED: cd /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/GaudiExamples && /cvmfs/lhcb.cern.ch/lib/lhcb/LBSCRIPTS/LBSCRIPTS_v9r2p6/LbUtils/cmake/xenv --xml /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/config/Gaudi-build.xenv /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/bin/genconf.exe -o /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/GaudiExamples/genConf/GaudiExamples -p GaudiExamples --configurable-module=GaudiKernel.Proxy --configurable-default-name=Configurable.DefaultName --configurable-algorithm=ConfigurableAlgorithm --configurable-algtool=ConfigurableAlgTool --configurable-auditor=ConfigurableAuditor --configurable-service=ConfigurableService -i GaudiExamplespure virtual method calledterminate called without an active exception[4/6] Building CXX object GaudiPython/CMakeFiles/GaudiPythonDict.dir/GaudiPythonDict.cpp.oninja: build stopped: subcommand failed.make: *** [all] Error 1
and the following traceback:
#0 0x00007ffff61022c7 in raise () from /lib64/libc.so.6#1 0x00007ffff61039b8 in abort () from /lib64/libc.so.6#2 0x00007ffff6960dc3 in __gnu_cxx::__verbose_terminate_handler () at /afs/cern.ch/cms/CAF/CMSCOMM/COMM_ECAL/dkonst/GCC/build/contrib/gcc-8.2.0/src/gcc/8.2.0/libstdc++-v3/libsupc++/vterminate.cc:95#3 0x00007ffff6966f26 in __cxxabiv1::__terminate (handler=<optimized out>) at /afs/cern.ch/cms/CAF/CMSCOMM/COMM_ECAL/dkonst/GCC/build/contrib/gcc-8.2.0/src/gcc/8.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:47#4 0x00007ffff6966f61 in std::terminate () at /afs/cern.ch/cms/CAF/CMSCOMM/COMM_ECAL/dkonst/GCC/build/contrib/gcc-8.2.0/src/gcc/8.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:57#5 0x00007ffff6967c9f in __cxxabiv1::__cxa_pure_virtual () at /afs/cern.ch/cms/CAF/CMSCOMM/COMM_ECAL/dkonst/GCC/build/contrib/gcc-8.2.0/src/gcc/8.2.0/libstdc++-v3/libsupc++/pure.cc:50#6 0x00007ffff7bb16b6 in GaudiHandleArrayBase::setTypesAndNames(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiKernel.so#7 0x00007ffff279ea76 in ToolHandleArray<IMyTool>::ToolHandleArray<MyGaudiAlgorithm, void>(MyGaudiAlgorithm*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiExamples.so#8 0x00007ffff2792ce3 in MyGaudiAlgorithm::MyGaudiAlgorithm(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*) () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiExamples.so#9 0x00007ffff27a3f0e in std::_Function_handler<std::unique_ptr<IAlgorithm, std::default_delete<IAlgorithm> > (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*), Gaudi::PluginService::v2::Details::DefaultFactory<MyGaudiAlgorithm, Gaudi::PluginService::v2::Factory<IAlgorithm* (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*)> > >::_M_invoke(std::_Any_data const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*&&) () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiExamples.so#10 0x000000000043cae1 in std::unique_ptr<IAlgorithm, std::default_delete<IAlgorithm> > Gaudi::PluginService::v2::Factory<IAlgorithm* (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*)>::create<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ISvcLocator*) ()#11 0x0000000000433617 in configGenerator::genConfig(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()#12 0x000000000042def7 in main ()(gdb)
which looks like the base class constructor calling a virtual function implemented as part of the derived class, which hasn't been added to the vtable yet, as C++ (properly!) first calls the base class constructor (at which point it isn't known yet what derived class it will use!), and then 'continues' construction by constructing the derived class, which populates the vtable, and only then one can call virtual functions defined in the derived class...
so the problem here is that the GaudiHandleArrayBase constructor calls GaudiHandleArrayBase::setTypesAndNames which calls push_back, which is indeed a virtual function:
MyGaudiAlg DEBUG ToolHandleArray MyPublicToolHandleArrayProperty not used: not registering any of its Tools
which is not consistent with ToolHandle: ToolHandle is automatically retrieved unless the user code explicitly opts-out in initialize. For ToolHandleArray, the user code must opt-in... which forces one to write an initialize implementation, which in an opt-out model would not be necessary...
After removing the check for GaudiHandleArrayBase::retrieved() in AlgTool and Algorithm, the next problem appears:
MyGaudiAlg INFO ....initialization doneMyGaudiAlg DEBUG input handles: 3MyGaudiAlg DEBUG output handles: 1MyGaudiAlg DEBUG Registering all Tools in ToolHandleArray MyPublicToolHandleArrayProperty
i.e. the tool handles in the array are registered after the search for data handles, so any handles in the tools referenced in a tool array are not taken into account.
And if that isn't enough, the next-to-next problem already appears:
MyGaudiAlg DEBUG Registering all Tools in ToolHandleArray MyPublicToolHandleArrayProperty *** Break *** segmentation violation#4 <signal handler called>#5 0x00007f47e7d64d99 in Gaudi::Algorithm::initToolHandles() const () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiKernel.so#6 0x00007f47e7d67d78 in Gaudi::Algorithm::sysInitialize() () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiKernel.so#7 0x00007f47e7e0259e in MinimalEventLoopMgr::initialize() () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiKernel.so#8 0x00007f47e61acee5 in EventLoopMgr::initialize() () from /project/bfys/graven/master/Gaudi/build.x86_64+avx2+fma-centos7-gcc8-opt/lib/libGaudiCoreSvc.so
Registering the tools 'late' is presumably not a problem, as the individual tool handles are done at the same time.
Now, the SEGV is due to only calling get on the handles, and not retrieve -- I've added a commit to !960 (merged) which unifies the handling of individual tool handles, and tool handles which appear as part of tool handle array.
Sofar it looks like !960 (merged) indeed fixes all (known!) usage problems with ToolHandleArray... so !960 (merged) has been flagged as closing this issue.