Segfault with AddBinContent but not with Fill

I’m trying to rebin the axis of a 2D histogram, by repopulating a new histogram with AddBinContent. I’m getting segfaults, which are weird because it doesn’t seem to crash at the same line in the code each time I run, and the stack traces come out different. I post one of those stack traces at the bottom.

The code runs fine if I replace the AddBinContent with Fill. I attach the code and a file to run on to reproduce the problem. I tried both root 5.34.25 and 6.02.10. I’m doing these operations inside a larger script, and running that just causes the program to freeze.
smallfile.root (130 KB)

from ROOT import *
from array import array

def rebinX(histlist):
    ''' Rebin 2D histos in x according to a custom hard-coded
        binning as specified in getCustomXbins() 
        Uses Rene's suggestion here
        except uses AddBinConent instead of Fill to get proper errors, which also requires
        SetEntries to be called. Sumw2 has to be called after all of this. 
    # custom pt bins
    print "getting custom x bins..."
    (nbins_x, xbins) = getCustomXbins()
    histlist_rebinned = []
    for hist in histlist:
        xaxis = hist.GetXaxis()
        yaxis = hist.GetYaxis()
        hname = hist.GetName()+'_RebinX'
        h_rebinned = TH2D(hname, hist.GetTitle(), nbins_x, xbins, yaxis.GetNbins(), yaxis.GetXmin(), yaxis.GetXmax())

        # populate new histogram
        print "populating new rebinned histo..."
        for xbin in range(1, xaxis.GetNbins()+1):
            for ybin in range(1, yaxis.GetNbins()+1):
                # To use AddBinContent the global bin nr must be found
                x = xaxis.GetBinCenter(xbin)
                y = yaxis.GetBinCenter(ybin)
                ### If AddBinContent is replaced by Fill, segfault is no longer present
                h_rebinned.AddBinContent(hist.FindBin(x, y), hist.GetBinContent(xbin, ybin))

        print "Done populating, now calling SetEntries and Sumw2 before appending to new histlist"

    return histlist_rebinned

def getCustomXbins():
    nbins_x_custom = 37 
    array_x_custom = [0.]*(nbins_x_custom+1)
    for b in range(6+1):   array_x_custom[b   ] = 0.1  + b*0.025;
    for b in range(5+1):   array_x_custom[b+6 ] = 0.25 + b*0.05;
    for b in range(20+1):  array_x_custom[b+11] = 0.5  + b*0.1;
    for b in range(4+1):   array_x_custom[b+31] = 2.5  + b*0.250;
    for b in range(1+1):   array_x_custom[b+35] = 3.5  + b*0.5;
    array_x_custom[37] = 200.
    return (nbins_x_custom, array('d',array_x_custom))


# open file and get histos
file = TFile.Open("smallfile.root", "READ")
h1 = file.Get("SelectedMigratedPtPrimaryTracks_PtEta")
h2 = file.Get("SelectedMigratedEtaPrimaryTracks_PtEta")
h3 = file.Get("MigratedOutPtPrimaryTruthTracks_PtEta")
h4 = file.Get("SelectedTracks_PtEta")

histlist = [h1,h2,h3,h4]
for hist in histlist: hist.SetDirectory(0)

print "Getting hists with rebinned x axis."
histlist = rebinX(histlist)

An example of a segfault

#6 0x00007f26d331170c in clang::CodeGen::CodeGenModule::EmitTargetMetadata() () from /cvmfs/
#7 0x00007f26d2e28fea in cling::IncrementalParser::codeGenTransaction(cling::Transaction*) () from /cvmfs/
#8 0x00007f26d2e28d8f in cling::IncrementalParser::commitTransaction(cling::Transaction*) () from /cvmfs/
#9 0x00007f26d2e2b0d4 in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) () from /cvmfs/
#10 0x00007f26d2dd7779 in cling::Interpreter::DeclareInternal(std::basic_string<char, std::char_traits, std::allocator > const&, cling::CompilationOptions const&, cling::Transaction**) const () from /cvmfs/
#11 0x00007f26d2dd78b8 in cling::Interpreter::declare(std::basic_string<char, std::char_traits, std::allocator > const&, cling::Transaction**) () from /cvmfs/
#12 0x00007f26d2dd7979 in cling::Interpreter::DeclareCFunction(llvm::StringRef, llvm::StringRef, bool) () from /cvmfs/
#13 0x00007f26d2dd7f2f in cling::Interpreter::compileFunction(llvm::StringRef, llvm::StringRef, bool, bool) () from /cvmfs/
#14 0x00007f26d2d4f316 in TClingCallFunc::compile_wrapper(std::basic_string<char, std::char_traits, std::allocator > const&, std::basic_string<char, std::char_traits, std::allocator > const&, bool) () from /cvmfs/
#15 0x00007f26d2d51aab in TClingCallFunc::make_wrapper() () from /cvmfs/
#16 0x00007f26d2d557e0 in TClingCallFunc::IFacePtr() () from /cvmfs/
#17 0x00007f26d2d55822 in TClingCallFunc::Exec(void*, TInterpreterValue*) () from /cvmfs/
#18 0x00007f26d9dfb9d5 in PyROOT::TVoidExecutor::Execute(CallFunc_t*, void*, bool) () from /cvmfs/
#19 0x00007f26d9dfb3f0 in PyROOT::TMethodHolder::CallSafe(void*, bool) () from /cvmfs/
#20 0x00007f26d9df947d in PyROOT::TMethodHolder::Execute(void*, bool) () from /cvmfs/
#21 0x00007f26d9df8b72 in PyROOT::TMethodHolder::operator()(PyROOT::ObjectProxy*, _object*, _object*, long, bool) () from /cvmfs/
#22 0x00007f26d9de550d in PyROOT::(anonymous namespace)::mp_call(PyROOT::MethodProxy*, _object*, _object*) () from /cvmfs/
#23 0x00007f26e11c7703 in PyObject_Call () from /cvmfs/…/lib/
#24 0x00007f26e127a2a1 in PyEval_EvalFrameEx () at /build/hegner/afs_build/lcgcmake-build/externals/Python/src/Python/2.7.4/Python/ceval.c:4239
#25 0x00007f26e127e5ed in PyEval_EvalCodeEx () at /build/hegner/afs_build/lcgcmake-build/externals/Python/src/Python/2.7.4/Python/ceval.c:3253
#26 0x00007f26e11f91b5 in function_call () from /cvmfs/…/lib/
#27 0x00007f26e11c7703 in PyObject_Call () from /cvmfs/…/lib/
#28 0x00007f26e1279976 in PyEval_EvalFrameEx () at /build/hegner/afs_build/lcgcmake-build/externals/Python/src/Python/2.7.4/Python/ceval.c:4334
#29 0x00007f26e127e5ed in PyEval_EvalCodeEx () at /build/hegner/afs_build/lcgcmake-build/externals/Python/src/Python/2.7.4/Python/ceval.c:3253
#30 0x00007f26e11f90e0 in function_call () from /cvmfs/…/lib/
#31 0x00007f26e11c7703 in PyObject_Call () from /cvmfs/…/lib/
#32 0x00007f26e1277f87 in PyEval_CallObjectWithKeywords () at /build/hegner/afs_build/lcgcmake-build/externals/Python/src/Python/2.7.4/Python/ceval.c:3890
#33 0x00007f26e12a9bf7 in Py_Finalize () from /cvmfs/…/lib/
#34 0x00007f26e12bf725 in Py_Main () from /cvmfs/…/lib/
#35 0x00007f26e0558d5d in __libc_start_main () from /lib64/
#36 0x00000000004006d9 in _start ()

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File “/cvmfs/”, line 24, in _run_exitfuncs
func(*targs, **kargs)
File “/cvmfs/”, line 663, in cleanup
SystemError: void TROOT::EndOfProcessCleanups() =>
problem in C++; program state has been reset
Error in sys.exitfunc:
Traceback (most recent call last):
File “/cvmfs/”, line 24, in _run_exitfuncs
func(*targs, **kargs)
File “/cvmfs/”, line 663, in cleanup
SystemError: void TROOT::EndOfProcessCleanups() =>
problem in C++; program state has been reset


this line:h_rebinned.AddBinContent(hist.FindBin(x, y), hist.GetBinContent(xbin, ybin))will index the array position of bin “hist.FindBin(x, y)” in h_rebinned. But your getCustomXbins() made sure that the the nr. of xbins for h_rebinned is smaller than that for hist, so your indexing random memory. Don’t do that.