Skip to content

ListenerList in IncidentSvc should be std::list, not std::vector.

Scott Snyder requested to merge ssnyder/Gaudi:atlas-sss into atlas/v27r1

hi -

Running RecExCommon/myTopOptions.py in recent devval crashes in IncidentSvc:

 0x7f92ce5317e0 __restore_rt ??:0   + 0x7f92ce5317e0 [/lib64/libpthread.so.0 D[0xf7e0]]
 0x7f92a674da08 IncidentSvc::i_fireIncident(Incident const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /build2/atnight/localbuilds/nightlies/21.X.Y-VAL/GAUDI/rel_nightly/GaudiCoreSvc/src/IncidentSvc/IncidentSvc.cpp:214   + 0x358 [/afs/cern.ch/atlas/software/builds/nightlies/devval/GAUDI/rel_1/InstallArea/x86_64-slc6-gcc49-dbg/lib/libGaudiCoreSvc.so D[0x8a8a08]]
 0x7f92a674df08 IncidentSvc::fireIncident(Incident const&) /build2/atnight/localbuilds/nightlies/21.X.Y-VAL/GAUDI/rel_nightly/GaudiCoreSvc/src/IncidentSvc/IncidentSvc.cpp:254   + 0x58 [/afs/cern.ch/atlas/software/builds/nightlies/devval/GAUDI/rel_1/InstallArea/x86_64-slc6-gcc49-dbg/lib/libGaudiCoreSvc.so D[0x8a8f08]]
0x7f92a5520a82 AthenaEventLoopMgr::beginRunAlgorithms(EventInfo const&) /build2/atnight/localbuilds/nightlies/21.X.Y-VAL/AtlasCore/rel_nightly/Control/AthenaServices/src/AthenaEventLoopMgr.cxx:532   + 0xb8 [/afs/cern.ch/atlas/software/builds/nightlies/devval/AtlasCore/rel_1/InstallArea/x86_64-slc6-gcc49-dbg/lib/libAthenaServices.so D[0x31ba82]]
...

What's happening is that IncidentSvc iterating over the list of registered listeners, calling the handler for each. (The incident here is BeginRun.) One of these handlers creates a tool, which in turn ends up calling addListener(). Now, the list of listeners held by IncidentSvc is a std::vector --- so adding a new one can invalidate iterators. So, we get a new listener added while we're in the middle of iterating over the vector. Whoops --- a crash.

See the attached stack trace for how this occurs. This trace was taken at the point where the vector of listeners was modified by an addListener() call.

In the previous version of Gaudi that we used, IncidentSvc stored the list of listeners as a std::list, so insertions and deletions didn't invalidate the iteration.

And this indeed seems to be the best fix for this. Everything still seems to work find if the vector is changed to a list, and the crash goes away. (An alternate might be to copy the vector before iterating over it, but that still gives the possibility of calling a listener that was removed from an incident handler.) stacktrace

Merge request reports