Pointer not allocated when adding RResultPtr to vector

When running the macro below with root -l pointer_not_allocated_error.cc, it throws the expected runtime_error and exits. However, when run from the root prompt, either with
root [0] .X pointer_not_allocated_error.cc
root [0] .L pointer_not_allocated_error.cc
root [1] pointer_not_allocated_error()
It instead exits with

root.exe(21452,0x116309dc0) malloc: *** error for object 0x7fbe097b7700: pointer being freed was not allocated
root.exe(21452,0x116309dc0) malloc: *** set a breakpoint in malloc_error_break to debug

Here is the code to reproduce the error:

  1 vector<ROOT::RDF::RResultPtr<TH1D>> pointer_not_allocated_error(){
  2     // Create a data frame with 100 rows
  3     ROOT::RDataFrame rdf(100);
  5     // Define a new column `x` that contains random numbers and create a histogram
  6     ROOT::RDF::RResultPtr<TH1D> h = rdf.Define("x", [](){ return gRandom->Rndm(); }).Histo1D("x");
  8     // Add the histogram to a vector
  9     vector<ROOT::RDF::RResultPtr<TH1D>> histograms;
 10     histograms.push_back(h);
 12     // Attempt to throw an error
 13     throw std::runtime_error("intended error throw for debugging");
 15     return histograms;
 16 }

Why is this happening and what is the proper way to create such a vector of histograms?

ROOT Version: 6.26/04, from conda-forge
Platform: macos 10.15.7

Hi @JSHeines ,

Thank you for the simple reproducer.
That’s the proper way of creating a vector of RDF results.
The crash is weird, it looks like something goes terribly wrong in the interpreter. I can reproduce this with a recent build of ROOT master on Linux. @hahnjo , @jalopezg , can you tell what’s going on here?


a workaround seems to be to catch that exception before it reaches the interpreter’s global scope:

root [1] .L pointer_not_allocated.C
root [2] try { pointer_not_allocated_error(); } catch(...) { }
root [3] pointer_not_allocated_error()
free(): double free detected in tcache 2


The gdb backtrace at the point of the double free:

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff72a1503 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#2  0x00007ffff7251958 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff723b53d in __GI_abort () at abort.c:79
#4  0x00007ffff729563e in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff73b4432 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#5  0x00007ffff72ab22c in malloc_printerr (str=str@entry=0x7ffff73b6ff8 "free(): double free detected in tcache 2") at malloc.c:5660
#6  0x00007ffff72ad587 in _int_free (av=0x7ffff73f1ba0 <main_arena>, p=0x55555d902a90, have_lock=have_lock@entry=0) at malloc.c:4469
#7  0x00007ffff72af9f3 in __GI___libc_free (mem=<optimized out>) at malloc.c:3385
#8  0x00007fffedc5c7f4 in std::_Vector_base<ROOT::RDF::RResultPtr<TH1D>, std::allocator<ROOT::RDF::RResultPtr<TH1D> > >::~_Vector_base (this=0x555558836140) at /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/stl_vector.h:366
#9  0x00007fffee94194a in (anonymous namespace)::AllocatedValue::Release (this=0x555558836120) at ../interpreter/cling/lib/Interpreter/Value.cpp:124
#10 0x00007fffee941bc9 in cling::Value::~Value (this=0x7fffffffa4c0, __in_chrg=<optimized out>) at ../interpreter/cling/lib/Interpreter/Value.cpp:185
#11 0x00007fffee6ca4d9 in TCling::ProcessLine (this=0x5555555ee330, line=0x555556425650 ".X  /tmp/./pointer_not_allocated_error.C", error=0x7fffffffb5c0) at ../core/metacling/src/TCling.cxx:2633
#12 0x00007fffee6cdb30 in TCling::ProcessLineSynch (this=0x5555555ee330, line=0x555556425650 ".X  /tmp/./pointer_not_allocated_error.C", error=0x7fffffffb5c0) at ../core/metacling/src/TCling.cxx:3524
#13 0x00007ffff7acde01 in TApplication::ExecuteFile (file=0x55555644dbc3 "pointer_not_allocated_error.C", error=0x7fffffffb5c0, keep=false) at ../core/base/src/TApplication.cxx:1675
#14 0x00007ffff7acd520 in TApplication::ProcessFile (this=0x5555555d6350, file=0x55555644dbc3 "pointer_not_allocated_error.C", error=0x7fffffffb5c0, keep=false) at ../core/base/src/TApplication.cxx:1547
#15 0x00007ffff7acd335 in TApplication::ProcessLine (this=0x5555555d6350, line=0x55555644dbc0 ".x pointer_not_allocated_error.C", sync=false, err=0x7fffffffb5c0) at ../core/base/src/TApplication.cxx:1520
#16 0x00007ffff7fa6803 in TRint::ProcessLineNr (this=0x5555555d6350, filestem=0x7ffff7fb6967 "ROOT_prompt_", line=0x55555644dbc0 ".x pointer_not_allocated_error.C", error=0x7fffffffb5c0) at ../core/rint/src/TRint.cxx:818
#17 0x00007ffff7fa5dff in TRint::HandleTermInput (this=0x5555555d6350) at ../core/rint/src/TRint.cxx:648
#18 0x00007ffff7fa3309 in TTermInputHandler::Notify (this=0x55555645ec20) at ../core/rint/src/TRint.cxx:133
#19 0x00007ffff7fa7f89 in TTermInputHandler::ReadNotify (this=0x55555645ec20) at ../core/rint/src/TRint.cxx:125
#20 0x00007ffff7c6bcb8 in TUnixSystem::CheckDescriptors (this=0x55555557e800) at ../core/unix/src/TUnixSystem.cxx:1306
#21 0x00007ffff7c6af52 in TUnixSystem::DispatchOneEvent (this=0x55555557e800, pendingOnly=false) at ../core/unix/src/TUnixSystem.cxx:1061
#22 0x00007ffff7b47da9 in TSystem::InnerLoop (this=0x55555557e800) at ../core/base/src/TSystem.cxx:406
#23 0x00007ffff7b47b25 in TSystem::Run (this=0x55555557e800) at ../core/base/src/TSystem.cxx:356
#24 0x00007ffff7acdfb1 in TApplication::Run (this=0x5555555d6350, retrn=false) at ../core/base/src/TApplication.cxx:1691
#25 0x00007ffff7fa517f in TRint::Run (this=0x5555555d6350, retrn=false) at ../core/rint/src/TRint.cxx:501
#26 0x00005555555554df in main (argc=1, argv=0x7fffffffdb68) at ../main/src/rmain.cxx:84
1 Like

Hi @JSHeines, @eguiraud,

Thanks for reporting! Indeed, I was able to also reproduce the issue.

This became [cling] Non-void returning function that throws may cause double free · Issue #11494 · root-project/root · GitHub; see the full explanation of the issue there. It’s on my backlog now. I’ll try to work on it soon-ish.