From 8f9957469f3a208a28dd545fd1b6b44219100349 Mon Sep 17 00:00:00 2001 From: Vincenzo Eduardo Padulano Date: Fri, 10 May 2024 14:57:47 +0200 Subject: [PATCH] [df] Delete allocated node before throwing error In the jitted version of the `Vary` transformation a node is allocated on the heap and its address is passed down to the function `JitVariationHelper`, which is also responsible for deleting the allocated memory. In case a mismatch in the return type of the jitted function given to the Vary call is detected, we throw an error to inform the user they should return an RVec for the Vary to properly work. This means that the call to JitVariationHelper does not happen, thus the memory of the node is not deallocated. This commit corrects that behaviour by properly deleting the pointer before throwing the exception. Thanks to the address sanitizer: ``` Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7f28c78d9e28 in operator new(unsigned long) (/lib64/libasan.so.8+0xd9e28) (BuildId: 2b657470ea196ba4342e3bd8a3cc138b1e200599) #1 0xb711e0 in std::shared_ptr* ROOT::Internal::RDF::MakeSharedOnHeap(std::shared_ptr const&) /home/vpadulan/Programs/rootproject/rootbuild/master-a73f11dfc5-testing-asan/include/ROOT/RDF/InterfaceUtils.hxx:370 #2 0xb843a8 in ROOT::RDF::RInterface::JittedVaryImpl(std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::basic_string_view >, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, std::basic_string_view >, bool) /home/vpadulan/Programs/rootproject/rootbuild/master-a73f11dfc5-testing-asan/include/ROOT/RDF/RInterface.hxx:3108 ``` --- tree/dataframe/src/RDFInterfaceUtils.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tree/dataframe/src/RDFInterfaceUtils.cxx b/tree/dataframe/src/RDFInterfaceUtils.cxx index b0c2bbb8156f3..93c75199237ba 100644 --- a/tree/dataframe/src/RDFInterfaceUtils.cxx +++ b/tree/dataframe/src/RDFInterfaceUtils.cxx @@ -777,10 +777,14 @@ BookVariationJit(const std::vector &colNames, std::string_view vari const auto funcName = DeclareFunction(parsedExpr.fExpr, parsedExpr.fVarNames, exprVarTypes); const auto type = RetTypeOfFunc(funcName); - if (type.rfind("ROOT::VecOps::RVec", 0) != 0) + if (type.rfind("ROOT::VecOps::RVec", 0) != 0) { + // Avoid leak + delete upcastNodeOnHeap; + upcastNodeOnHeap = nullptr; throw std::runtime_error( "Jitted Vary expressions must return an RVec object. The following expression returns a " + type + " instead:\n" + parsedExpr.fExpr); + } auto colRegisterCopy = new RColumnRegister(colRegister); const auto colRegisterAddr = PrettyPrintAddr(colRegisterCopy);