-
Notifications
You must be signed in to change notification settings - Fork 99
Description
Describe the bug
Running the FairRunAna task with an input parameter file containing any ParSet (such as FairGeoParSet) leads to Segmentation fault in the end of the program.
Cause
delete keyword and no ownership
Further explanation
When running the simulation, FairRunSim automatically put FairGeoParSet into the output parameter file. When using the output file as the input file for FairRunAna, it automatically load the parameter and put it into the container list, which will be eventually written to another output parameter file, including all this member variables:
FairRoot/fairroot/base/sim/FairGeoParSet.h
Lines 72 to 79 in 99be5f4
| protected: | |
| /// List of FairGeoNodes for sensitive volumes | |
| TObjArray* fGeoNodes; //! | |
| /// Full Geometry | |
| TGeoManager* fGeom; | |
| ClassDefOverride(FairGeoParSet, 1); | |
From here, you could see the TGeoManager will also be written to the file.
So when and where will the parameters be written to the output file? The answer is in the destructor of FairRun when it tries to delete FairRuntimeDb.
FairRoot/fairroot/base/steer/FairRun.cxx
Lines 81 to 104 in 99be5f4
| FairRun::~FairRun() | |
| { | |
| LOG(debug) << "Enter Destructor of FairRun"; | |
| // So that FairRootManager does not try to delete these, because we will do that: | |
| fRootManager->SetSource(nullptr); | |
| fRootManager->SetSink(nullptr); | |
| if (fTask) { | |
| // FairRunAna added it, but let's remove it here, because we own it | |
| gROOT->GetListOfBrowsables()->Remove(fTask); | |
| delete fTask; // There is another tasklist in MCApplication, | |
| } | |
| // but this should be independent | |
| if (fIsMaster) { | |
| // who is responsible for the RuntimeDataBase? | |
| delete fRtdb; | |
| } | |
| if (fRunInstance == this) { | |
| // Do not point to a destructed object! | |
| fRunInstance = nullptr; | |
| } | |
| LOG(debug) << "Leave Destructor of FairRun"; | |
| } |
But before it comes to this, the destructor of FairRunAna must also be called. And what its destructor does is:
FairRoot/fairroot/base/steer/FairRunAna.cxx
Lines 93 to 108 in 99be5f4
| FairRunAna::~FairRunAna() | |
| { | |
| // delete fFriendFileList; | |
| delete fField; | |
| if (gGeoManager) { | |
| if (gROOT->GetVersionInt() >= 60602) { | |
| gGeoManager->GetListOfVolumes()->Delete(); | |
| gGeoManager->GetListOfShapes()->Delete(); | |
| } | |
| delete gGeoManager; | |
| } | |
| if (fgRinstance == this) { | |
| // Do not point to a destructed object! | |
| fgRinstance = nullptr; | |
| } | |
| } |
So it deletes the TGeoManager object and all its volumes. But at the same time, FairGeoParSet also have a reference to this TGeoManager, which is ready to be written to the parameter file. When the writing occurs, TGeoManager already got deleted and BOOM we have segmentation fault!
Temporary solution
Remove everything in FairRunAna destructor. Or write all parameters before calling FairRunAna destructor:
run->GetRuntimeDb()->writeContainers();(several hours down to the drain :( )