SetDirectory triggers a seg fault

ROOT Version: 6.28/00 (conda install root -c conda-forge)
Platform: macOS Ventura 13.4
Compiler: Apple clang version 14.0.3 (clang-1403.

I have histograms in a ROOT file that was analyzed a few years ago without any problem. But when a new student tried to use it and the analysis macro, he found that the macro always crashes with a segmentation fault.

The code below is a minimum one to reproduce the issue.

void crash () {
  auto directory = gDirectory; // crashes
  //auto directory = gROOT; // OK
  TFile f("test.root");
  auto h = (TH1D*)f.Get("signal")->Clone("cloned");
  std::cout << "File closed" << std::endl;
  delete h; // crashes here
  std::cout << "Cloned histogram has been deleted" << std::endl;

In the 2nd line, if I copy gDirectory to directory before opening the ROOT file, deleting the cloned object causes a segmentation fault. But if I copy gROOT to directory, it does not.

In my understanding, saving gDirectory before opening a TFile, namely before switching to another directory, has been a valid and standard step for many years.

What is the problem of my code?

You can download the file from the Dropbox link below.

The issue does not happen when I use another TFile that I created for a test. Therefore maybe the above file is broken.

root [0] .x crash.C
File closed

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TList::AddLast(TObject*) (no debug info)
[<unknown binary>] (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::Interpreter::EvaluateInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::MetaSema::actOnxCommand(llvm::StringRef, llvm::StringRef, cling::Value*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::MetaParser::isXCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TApplication::ExecuteFile(char const*, int*, bool) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TRint::ProcessLineNr(char const*, char const*, int*) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TRint::HandleTermInput() (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TUnixSystem::CheckDescriptors() (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TMacOSXSystem::DispatchOneEvent(bool) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TSystem::InnerLoop() (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TSystem::Run() (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TApplication::Run(bool) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/lib/] TRint::Run(bool) (no debug info)
[/Users/oxon/anaconda3/envs/lab309/bin/root.exe] main (no debug info)
[/usr/lib/dyld] start (no debug info)
Root > 

It also crashes with the following M1 Mac environment

ROOT Version: 6.26/06
Platform: macOS 13.4
Compiler: Apple clang version 14.0.3 (clang-1403. Target: arm64-apple-darwin22.5.0

but it does not on an Intel Mac with an a bit old ROOT.

ROOT Version: 6.22/02
Platform: macOS 10.15.7
Compiler: clang version 10.0.1 Target: x86_64-apple-darwin19.6.0

Is there any critical change in ROOT directories between 6.22 and 6.26?

I guess @pcanal can help you.

Changing auto with TDirectory* is a workaround.

  TDirectory* directory = gDirectory;
1 Like
TDirectory* directory = gDirectory;

is the right solution.

auto directory = gDirectory; // crashes

is the moral equivalent (not technically, lots of technical details involved) of:

TDirectory &directory = gDirectory;

and so when doing:


is actually does the equivalent of

h->SetDirectory( &f );

in your example.

Thank you Philippe.

I found a similar explanation here.

I was not aware that TDirectoryAtomicAdapter was introduced in 2020. The macro that had my issue was written by the student before the implementation of TDirectoryAtomicAdapter.

I will use TDirectory* or gROOT instead.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.