Skip to content

[DF] Crash in multi-thread Snapshot in sub-directory #8226

@eguiraud

Description

@eguiraud

Describe the bug

The following is a self-contained reproducer:

#include <ROOT/RDataFrame.hxx>

int main()
{
   ROOT::RDataFrame(1000).Define("x", [] { return 42; }).Snapshot<int>("t", "f.root", {"x"});

   ROOT::EnableImplicitMT();
   auto df_bkg = ROOT::RDataFrame("t", "f.root");
   ROOT::RDF::RSnapshotOptions opts;
   opts.fAutoFlush = 10;
   df_bkg.Snapshot<int>("somedir/DecayTree", "bkg.root", {"x"}, opts);
}

The cause of the crash is a use-after-delete or a double-delete, caused by the following lines in TFileMerger::MergeOne which wrongly setup the subdirectory (owned by the parent file, owned by RDF) for deletion. Deletion of the subdirectory in turn causes the deletion of the output TTree that RDF is still using:

556    TList dirtodelete;
557    auto getDirectory = [&dirtodelete](TDirectory *parent, const char *name, const TString &pathname)
558    {
559       TDirectory *result = dynamic_cast<TDirectory*>(parent->GetList()->FindObject(name));
560       if (!result)
561          result = parent->GetDirectory(pathname);
562       else
563          dirtodelete.Add(result);
564
565       return result;
566    };

The bug affects any application using TFileMerger this way, of course, not just RDataFrame::Snapshot, but that's the most prominent case.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions