Bus error when creating a histogram in O2

Hi All,

I am having a strange problem when I run a macro that creates a simple histogram for analyzing TRD hits. As a minimal working example, the following macro works:

using namespace o2::trd;

int trd_example_macro()
{
  auto fin = TFile::Open("o2sim_HitsTRD.root");
  TTree *tree = (TTree *)fin->Get("o2sim");
  TBranch *br = tree->GetBranch("TRDHit");
  std::vector<o2::trd::HitType> *hits;
  br->SetAddress(&hits);

  const int nev = tree->GetEntries();
  for (int entry = 0; entry < nev; ++entry)
  {
    tree->GetEntry(entry);
    for (const auto &hit : *hits)
    {
      int q = hit.GetHitValue();
      std::cout << "Deposited charge is " << q << std::endl;
    }
  }
  return 0;
}

It prints what it should, as expected, but when adding a simple histogram, it breaks. The following macro:

using namespace o2::trd;

int trd_example_macro()
{
  auto fin = TFile::Open("o2sim_HitsTRD.root");
  TTree *tree = (TTree *)fin->Get("o2sim");
  TBranch *br = tree->GetBranch("TRDHit");
  std::vector<o2::trd::HitType> *hits;
  br->SetAddress(&hits);

  TH1F *hist = new TH1F("hist", ";Deposited Charge;Counts", 101, 0, 100); // problematic histogram

  const int nev = tree->GetEntries();
  for (int entry = 0; entry < nev; ++entry)
  {
    tree->GetEntry(entry);
    for (const auto &hit : *hits)
    {
      int q = hit.GetHitValue();
      hist->Fill(q);
      // std::cout << "Deposited charge is " << q << std::endl;
    }
  }
  return 0;
}

ends with a bus error:

[O2/latest] ~/work/alice/tmp $> root -l ../trd_example_macro.C
root [0] 
Processing ../trd_example_macro.C...

 *** Break *** bus error
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libRIO.6.20.08.so] int TStreamerInfoActions::VectorLooper::ReadBasicType<int>(TBuffer&, void*, void const*, TStreamerInfoActions::TLoopConfiguration const*, TStreamerInfoActions::TConfiguration const*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libRIO.6.20.08.so] TBufferFile::ApplySequence(TStreamerInfoActions::TActionSequence const&, void*, void*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libTree.6.20.08.so] TBranchElement::ReadLeavesCollectionMember(TBuffer&) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libTree.6.20.08.so] TBranch::GetEntry(long long, int) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libTree.6.20.08.so] TBranchElement::GetEntry(long long, int) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libTree.6.20.08.so] TBranchElement::GetEntry(long long, int) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libTree.6.20.08.so] TTree::GetEntry(long long, int) (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] 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/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::MetaSema::actOnxCommand(llvm::StringRef, llvm::StringRef, cling::Value*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::MetaParser::isXCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCling.6.20.08.so] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libCore.6.20.08.so] TApplication::ExecuteFile(char const*, int*, bool) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libRint.6.20.08.so] TRint::ProcessLineNr(char const*, char const*, int*) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/lib/libRint.6.20.08.so] TRint::Run(bool) (no debug info)
[/Users/lopez/work/alice/sw/osx_x86-64/ROOT/v6-20-08-alice1-1/bin/root.exe] main (no debug info)
[/usr/lib/system/libdyld.dylib] start (no debug info)
[<unknown binary>] (no debug info)
Root > 
root [1] 

Additionally, if I compile the macro with the appropriate headers, like if I wanted to add it to the O2 framework:

#if !defined(__CLING__) || defined(__ROOTCLING__)
#include <TFile.h>
#include <TTree.h>
#include <TBranch.h>
#include <TH1F.h>

#include "TRDSimulation/Detector.h"

#include <iostream>
#include <numeric>
#include <map>
#include <vector>
#endif

using namespace o2::trd;

int trd_example_macro()
{
  auto fin = TFile::Open("o2sim_HitsTRD.root");
  TTree *tree = (TTree *)fin->Get("o2sim");
  TBranch *br = tree->GetBranch("TRDHit");
  std::vector<o2::trd::HitType> *hits;
  br->SetAddress(&hits);

  TH1F *hist = new TH1F("hist", ";Deposited Charge;Counts", 101, 0, 100);

  const int nev = tree->GetEntries();
  for (int entry = 0; entry < nev; ++entry)
  {
    tree->GetEntry(entry);
    for (const auto &hit : *hits)
    {
      int q = hit.GetHitValue();
      hist->Fill(q);
      // std::cout << "Deposited charge is " << q << std::endl;
    }
  }
  return 0;
}

I get the following error:

root [0] .L ../trd_example_macro.C+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/lopez/work/alice/tmp/./../trd_example_macro_C.so
In file included from /Users/lopez/work/alice/tmp/./../trd_example_macro_C_ACLiC_dict.cxx:41:
In file included from /Users/lopez/work/alice/tmp/./../trd_example_macro.C:8:
In file included from /Users/lopez/work/alice/sw/osx_x86-64/O2/v1.3.0-1/include/TRDSimulation/Detector.h:15:
/Users/lopez/work/alice/sw/osx_x86-64/O2/v1.3.0-1/include/DetectorsBase/Detector.h:258:14: warning: unused parameter 'data' [-Wunused-parameter]
    [](void* data, void* hint) { delete static_cast<TMessage*>(hint); }, tmsg);
             ^
1 warning generated.
root [1] trd_example_macro()
(int) 0

 *** Break *** segmentation violation
root.exe(37646,0x101d9edc0) malloc: Incorrect checksum for freed object 0x7f8397764cf8: probably modified after being freed.
Corrupt value: 0x42d09a50c39c7447
root.exe(37646,0x101d9edc0) malloc: *** set a breakpoint in malloc_error_break to debug

I use o2-sim -n 1 -m PIPE MAG TRD to create the hits file; of course, I have tried more events. I am using a very recent version of O2@dev, as well as alidist in a clean environment. I tried to run the macro in MacOS 10.15 as well as in Ubuntu 18.04 and 20.04 with the same results.

I wanted to make a JIRA ticket for this, but I can be making a mistake here.

The answer is that pointers need nullptr initialization. So that changing std::vector<o2::trd::HitType> *hits; to std::vector<o2::trd::HitType> *hits = nullprt; fixed the problem.