Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault during writing FairGeoParset with FairRunAna #1593

Open
YanzhaoW opened this issue Oct 29, 2024 · 2 comments
Open

Segmentation fault during writing FairGeoParset with FairRunAna #1593

YanzhaoW opened this issue Oct 29, 2024 · 2 comments

Comments

@YanzhaoW
Copy link

YanzhaoW commented Oct 29, 2024

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

@YanzhaoW YanzhaoW changed the title Segmentation fault during writing FairGeoParset with FairRun Segmentation fault during writing FairGeoParset with FairRunAna Oct 29, 2024
@fuhlig1
Copy link
Member

fuhlig1 commented Oct 30, 2024

@YanzhaoW,

thanks for the report. Do you have a short demonstrator to reproduce the problem?
Currently I am wondering why the problem wasn't seen before.

@YanzhaoW
Copy link
Author

YanzhaoW commented Nov 1, 2024

@fuhlig1

Hi, sorry that I don't have a "short" example to reproduce the problem. The problem occurs when I use R3BRoot and later I found it's due to the memory mismanagement from FairRoot.

Currently I am wondering why the problem wasn't seen before.

Use after deletion is always an undefined behaviour, which doesn't guarantee its occurrence. Also following situations can also hide this bug:

  • The destructor of FairRunAna is not called. This can happen if someone initialises it with new operator and forgets to delete it in the end.
  • Parameters are saved before calling the destructor of FairRun.

Is there any existing test that could potentially be used for this detecting this bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants