Skip to content

Segmentation fault during writing FairGeoParset with FairRunAna #1593

Open
@YanzhaoW

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:

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.

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:

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 :( )

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions