Skip to content

Memory leaks with Clone() #17659

Open
Open
@rlalik

Description

Check duplicate issues.

  • Checked for duplicates

Description

I have simple code cloning TF1 object with Clone() (MWE below) compiled following way:

g++ example3.cpp -fsanitize=address,undefined -o example3 -isystem /usr/include/root /usr/lib64/root/libHist.so.6.34.02 /usr/lib64/root/libCore.so.6.34.02

When compiling with Clone() I have several memory leaks:

=================================================================
==29703==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 736 byte(s) in 10 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f87b873c in TStorage::ObjectAlloc(unsigned long) (/usr/lib64/root/libCore.so.6.34+0x20b73c)

Indirect leak of 512 byte(s) in 8 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f749454a in std::vector<TStreamerInfoActions::TConfiguredAction, std::allocator<TStreamerInfoActions::TConfiguredAction> >::reserve(unsigned long) (/usr/lib64/root/libRIO.so.6.34+0x23a54a)

Indirect leak of 328 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfc18 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfbc18)
    #1 0x7f79f7429717 in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf717)

Indirect leak of 192 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f87b873c in TStorage::ObjectAlloc(unsigned long) (/usr/lib64/root/libCore.so.6.34+0x20b73c)
    #2 0x7f79f73e160a in TStreamerInfo::GenerateInfoForPair(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, unsigned long, unsigned long) (/usr/lib64/root/libRIO.so.6.34+0x18760a)

Indirect leak of 184 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f87b873c in TStorage::ObjectAlloc(unsigned long) (/usr/lib64/root/libCore.so.6.34+0x20b73c)
    #2 0x7f79f73e1584 in TStreamerInfo::GenerateInfoForPair(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, unsigned long, unsigned long) (/usr/lib64/root/libRIO.so.6.34+0x187584)

Indirect leak of 128 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfc18 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfbc18)
    #1 0x7f79f881da8b in TObjArray::Init(int, int) (/usr/lib64/root/libCore.so.6.34+0x270a8b)

Indirect leak of 80 byte(s) in 2 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f74203e4 in TStreamerInfo::AddWriteAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c63e4)

Indirect leak of 80 byte(s) in 2 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f74254c1 in TStreamerInfo::AddWriteMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1cb4c1)

Indirect leak of 80 byte(s) in 2 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f74200f4 in TStreamerInfo::AddWriteAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c60f4)

Indirect leak of 80 byte(s) in 2 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f74205c9 in TStreamerInfo::AddReadTextAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c65c9)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f7411127  (/usr/lib64/root/libRIO.so.6.34+0x1b7127)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f742130f in TStreamerInfo::AddReadAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c730f)
    #2 0x7f79f74295d8 in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf5d8)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f741fb39 in TStreamerInfo::AddWriteTextAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c5b39)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f741fe4b in TStreamerInfo::AddWriteTextAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c5e4b)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f742130f in TStreamerInfo::AddReadAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c730f)
    #2 0x7f79f742956c in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf56c)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f741185c  (/usr/lib64/root/libRIO.so.6.34+0x1b785c)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f7421420 in TStreamerInfo::AddReadAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c7420)
    #2 0x7f79f74295d8 in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf5d8)

Indirect leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfa88 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfba88)
    #1 0x7f79f7421420 in TStreamerInfo::AddReadAction(TStreamerInfoActions::TActionSequence*, int, TStreamerInfo::TCompInfo*) (/usr/lib64/root/libRIO.so.6.34+0x1c7420)
    #2 0x7f79f742956c in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf56c)

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfc18 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfbc18)
    #1 0x7f79f87bb2e0 in TString::Clobber(int) (/usr/lib64/root/libCore.so.6.34+0x20e2e0)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfc18 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfbc18)
    #1 0x7f79f7429236 in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf236)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7f79f8fdfc18 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/14/libasan.so.8+0xfbc18)
    #1 0x7f79f742922a in TStreamerInfo::Compile() (/usr/lib64/root/libRIO.so.6.34+0x1cf22a)

SUMMARY: AddressSanitizer: 2784 byte(s) leaked in 41 allocation(s).

whereas the IsA()->New() code (which I took from void HFit::StoreAndDrawFitFunction() seems safe.

So, any odea why Clone() results with leaks? Should it be fixed? Should Clone() be not used?

Reproducer

MWE:

#include <TClass.h>
#include <TF1.h>

auto main() -> int
{
    auto f1 = std::make_unique<TF1>("f1", "gaus", -10, 10);
    f1->Print();

    // This has leaks
    auto aaa = f1->Clone();
    aaa->Print();
    delete aaa;

    // This has no leaks
    auto bbb = (TF1*)(f1->IsA()->New());
    f1->Copy(*bbb);
    bbb->Print();
    delete bbb;

    return 0;
}

ROOT version

Many version, cuurently 6.34.02

Installation method

Build from source (Gentoo)

Operating system

Linux

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions