Memory leak with basic TTree

Hello experts,

I’m currently facing a huge memory leak issue using very basic features of root.
Here, I simply create a TTree in a TFile and fill it with some random values.
You can see other includes, they are the one I use in the real code, I put them there in case they are responsible of this weird behavior.

#include "TCanvas.h"
#include "TChain.h"
#include "TError.h"
#include "TF1.h"
#include "TF2.h"
#include "TFile.h"
#include "TFitResultPtr.h"
#include "TFitResult.h"
#include "TGraph.h"
#include "TH1F.h"
#include "TH1D.h"
#include "TH1S.h"
#include "TH2.h"
#include "TH2F.h"
#include "TH3I.h"
#include "TLegend.h"
#include "TMath.h"
#include "TRandom.h"
#include "TROOT.h"
#include "TStopwatch.h"
#include "TString.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TThread.h"
#include "TTree.h"
#include "TTreeIndex.h"

struct Hit
{
  UShort_t  label  = 0; //Hit label
  Float_t   nrj    = 0; //energy
  ULong64_t time   = 0; //time
};

int main()
{
  Hit hit;
  srand48(time(0));
  TFile *file = new TFile("datafile.root", "recreate");
  TTree *tree = new TTree("DataTree", "DataTree");
  tree -> Branch("nrj",&hit.nrj);
  tree -> Branch("label",&hit.label);
  tree -> Branch("time",&hit.time);
  for (int i = 0; i<2000; i++)
  {
    hit.nrj = drand48()*5;
    hit.time = drand48()*5;
    hit.label = drand48()*5;
    tree -> Fill();
  }
  file -> cd();
  tree -> Write();
  file -> Write();
  file -> Close();
  delete tree, file;
  return 0;
}

But this seems to create a huge memory leak ! According to valgrind :

HEAP SUMMARY:
==9087==     in use at exit: 31,861,053 bytes in 47,701 blocks
==9087==   total heap usage: 146,174 allocs, 98,473 frees, 108,152,207 bytes allocated

==9087== LEAK SUMMARY:
==9087==    definitely lost: 16 bytes in 1 blocks
==9087==    indirectly lost: 32 bytes in 1 blocks
==9087==      possibly lost: 29,947,704 bytes in 31,421 blocks
==9087==    still reachable: 1,913,301 bytes in 16,278 blocks
==9087==                       of which reachable via heuristic:
==9087==                         stdstring          : 40 bytes in 1 blocks
==9087==                         newarray           : 16,640 bytes in 30 blocks
==9087==                         multipleinheritance: 14,688 bytes in 2 blocks
==9087==         suppressed: 0 bytes in 0 blocks

ERROR SUMMARY: 2048 errors from 126 contexts

one example of error spotted by valgrind:

Conditional jump or move depends on uninitialised value(s)
==9087==    at 0x4FD58B9: TStorage::UpdateIsOnHeap(unsigned int const volatile&, unsigned int volatile&) (in /usr/lib/libCore.so)
==9087==    by 0x5098A7E: TObjArray::TObjArray(int, int) (in /usr/lib/libCore.so)
==9087==    by 0x573FB72: TStreamerInfo::Streamer(TBuffer&) (in /usr/lib/libRIO.so)
==9087==    by 0x567F46B: TBufferFile::WriteObjectClass(void const*, TClass const*, bool) (in /usr/lib/libRIO.so)
==9087==    by 0x5686594: TBufferIO::WriteObjectAny(void const*, TClass const*, bool) (in /usr/lib/libRIO.so)
==9087==    by 0x5094C1E: TList::Streamer(TBuffer&) (in /usr/lib/libCore.so)
==9087==    by 0x571E478: TKey::TKey(TObject const*, char const*, int, TDirectory*) (in /usr/lib/libRIO.so)
==9087==    by 0x56E76E7: TFile::WriteStreamerInfo() (in /usr/lib/libRIO.so)
==9087==    by 0x56E6C62: TFile::Write(char const*, int, int) (in /usr/lib/libRIO.so)
==9087==    by 0x10948F: main (read2.cpp:65)

I really don’t understand much … This behavior also appears on my other debian machine with a complete different root version…


ROOT Version: 6.20/04
Platform: Ubuntu 18.04.6
Compiler: g++


Hi @CorentinH,

there is a memory leak because you are not deleting tree.

This line is not doing what you think it does:

  delete tree, file;

With the C++ comma operator, you have chained together the expressions delete tree and file in one line, but the expression file doesn’t to anything.

Either you do delete tree, delete file, or you best put the two statements in separate lines as is usually done in C++:

  delete tree;
  delete file;

I hope this helps!

Jonas

You only need:
delete file; // automatically deletes the tree, too

Hi,
Thank you for your prompt replies !
I did the changes that you tell me but there is unfortunately no changes in the behavior of the program.

#include "TCanvas.h"
#include "TChain.h"
#include "TError.h"
#include "TF1.h"
#include "TF2.h"
#include "TFile.h"
#include "TFitResultPtr.h"
#include "TFitResult.h"
#include "TGraph.h"
#include "TH1F.h"
#include "TH1D.h"
#include "TH1S.h"
#include "TH2.h"
#include "TH2F.h"
#include "TH3I.h"
#include "TLegend.h"
#include "TMath.h"
#include "TRandom.h"
#include "TROOT.h"
#include "TStopwatch.h"
#include "TString.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TThread.h"
#include "TTree.h"
#include "TTreeIndex.h"

struct Hit
{
  UShort_t  label  = 0; //Hit label
  Float_t   nrj    = 0; //energy
  Int_t     nrj2   = 0; //used if QDC2
  Int_t     nrj3   = 0; //used if QDC3
  Int_t     nrj4   = 0; //used if QDC4
  ULong64_t time   = 0; //time
  Bool_t    pileup = 0; //pile-up detection
  UInt_t    coinc  = 0; //Hit label
  UShort_t  mult   = 0; //Multiplicity of the hit
  Float_t   nrjcal = 0;
};

int main()
{
  Hit hit;
  srand48(time(0));
  TFile *file = new TFile("datafile.root", "recreate");
  TTree *tree = new TTree("DataTree", "DataTree");
  tree -> Branch("nrj",&hit.nrj);
  tree -> Branch("label",&hit.label);
  tree -> Branch("time",&hit.time);
  for (int i = 0; i<2000; i++)
  {
    hit.nrj = drand48()*5;
    hit.time = drand48()*5;
    hit.label = drand48()*5;
    tree -> Fill();
  }
  file -> cd();
  tree -> Write();
  file -> Write();
  file -> Close();
  delete file;
  return 0;
}
HEAP SUMMARY:
==16408==     in use at exit: 31,864,446 bytes in 47,714 blocks
==16408==   total heap usage: 146,194 allocs, 98,480 frees, 108,158,632 bytes allocated
==16408== 
==16408== LEAK SUMMARY:
==16408==    definitely lost: 16 bytes in 1 blocks
==16408==    indirectly lost: 32 bytes in 1 blocks
==16408==      possibly lost: 29,949,864 bytes in 31,423 blocks
==16408==    still reachable: 1,914,534 bytes in 16,289 blocks
==16408==                       of which reachable via heuristic:
==16408==                         stdstring          : 40 bytes in 1 blocks
==16408==                         newarray           : 16,640 bytes in 30 blocks
==16408==                         multipleinheritance: 14,688 bytes in 2 blocks
==16408==         suppressed: 0 bytes in 0 blocks
ERROR SUMMARY: 2048 errors from 126 contexts (suppressed: 0 from 0)

Hi @CorentinH,

thanks for following up and providing the full reproducer!

I think you have false positives from valgrind here. If I run your code in a look 1000 times and print the memory consumption, I can still see no leak:

#include <TSystem.h>
#include <TFile.h>
#include <TTree.h>

#include <iostream>
#include <stdlib.h>

struct Hit {
  UShort_t label = 0;  //Hit label
  Float_t nrj = 0;     //energy
  Int_t nrj2 = 0;      //used if QDC2
  Int_t nrj3 = 0;      //used if QDC3
  Int_t nrj4 = 0;      //used if QDC4
  ULong64_t time = 0;  //time
  Bool_t pileup = 0;   //pile-up detection
  UInt_t coinc = 0;    //Hit label
  UShort_t mult = 0;   //Multiplicity of the hit
  Float_t nrjcal = 0;
};

void recreateFile() {
  Hit hit;
  srand48(time(0));
  TFile *file = new TFile("datafile.root", "recreate");
  TTree *tree = new TTree("DataTree", "DataTree");
  tree->Branch("nrj", &hit.nrj);
  tree->Branch("label", &hit.label);
  tree->Branch("time", &hit.time);
  for (int i = 0; i < 2000; i++) {
    hit.nrj = drand48() * 5;
    hit.time = drand48() * 5;
    hit.label = drand48() * 5;
    tree->Fill();
  }
  file->cd();
  tree->Write();
  file->Write();
  file->Close();
  delete file;
}

void repro() {
  ProcInfo_t pinfo;
  for (std::size_t i = 0; i < 10000; ++i) {
    recreateFile();

    if (i % 100 == 0) {
      gSystem->GetProcInfo(&pinfo);
      std::cout << i << " memory usage " << pinfo.fMemResident << " "
                << pinfo.fMemVirtual << std::endl;
    }
  }
}

Is there a way other than valgrind that you can observe the leak with? See also this write-up by Axel about why valgrind gives you false positives with ROOT:

If you can’t get the suppression file from $ROOTSYS, you can also find it here in the GitHub repository.

Hope this helps!
Jonas

Thank you for your reply
Here it seems you are running the code as macro. Maybe the behavior is different in a compiled code ?
Corentin

No, I don’t think so. When I wrap the repro() function in a main() and compile the file, I also get no memory increase, even if I use the same ROOT version as you on lxplus (6.20.04).

Hi,

I ran the following command :

valgrind ./run --suppression=/etc/root/valgrind-root.supp

Unfortunately I still get the exact same valgrind output !
Even using the code from the GitHub rep…

Corentin

I guess the order matters:
valgrind --suppressions=/etc/root/valgrind-root.supp ./run

Well, this still doesn’t work :

valgrind --suppressions=/etc/root/valgrind-root.supp ./run
(with a ‘s’ at the end of suppressionS :wink:, my mistake)

But still same behavior unfortunately…

In the first post, you mention “errors” (often hundreds of them) that have been present in ROOT for a long time.
You can easily see them with the “root.exe”:
valgrind --suppressions=/etc/root/valgrind-root.supp /usr/bin/root.exe -q -l

Yes, exactly these errors happen in general when you start a ROOT process. I think this is just from memory that ROOT allocates where valgrind can’t tell that it’s freed up in the end, even though we try our best to suppress these false positives with the suppression file.

Your code doesn’t have any leaks, as you can verify by running it in a loop many times and tracking the memory resident set size as I suggest. Sorry for this unsatisfying answer :slight_smile:

And valgrind actually reports it as such, and we are missing info from your side:

“definitely lost” and “indirectly lost” are those we must fix; there are not many and these might be covered by the suppressions file.

2048 errors, on the other hand, is worrying - unless they are all gone with the help of the suppression file. Could you post an example of an error that’s left after applying the suppression file? (In case you wonder: I’m checking this regularly and I don’t see any errors in current master, with the - simple - tests I run.)

For ROOT 6.26/04 (your binary distribution) on Ubuntu 22.04 / x86_64, I get two “Invalid read of size 8” (4 errors from 2 contexts) related to “dl_open”:

valgrind --suppressions=$(root-config --etcdir)/valgrind-root.supp $(root-config --bindir)/root.exe -q -l

==23097== Memcheck, a memory error detector
==23097== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==23097== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==23097== Command: /.../root_v6.26.04/bin/root.exe -q -l
==23097== 
==23097== Invalid read of size 8
==23097==    at 0x40286C8: strncmp (strcmp.S:172)
==23097==    by 0x400668D: is_dst (dl-load.c:216)
==23097==    by 0x400810E: _dl_dst_count (dl-load.c:253)
==23097==    by 0x400810E: expand_dynamic_string_token (dl-load.c:395)
==23097==    by 0x40082B7: fillin_rpath.isra.0 (dl-load.c:483)
==23097==    by 0x4008602: decompose_rpath (dl-load.c:654)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:696)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:677)
==23097==    by 0x400ABF5: _dl_map_object (dl-load.c:2165)
==23097==    by 0x4003494: openaux (dl-deps.c:64)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x4003C7B: _dl_map_object_deps (dl-deps.c:248)
==23097==    by 0x400EA0E: dl_open_worker_begin (dl-open.c:592)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400DF99: dl_open_worker (dl-open.c:782)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400E34D: _dl_open (dl-open.c:883)
==23097==    by 0x51416BB: dlopen_doit (dlopen.c:56)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x5225CF2: _dl_catch_error (dl-error-skeleton.c:227)
==23097==    by 0x51411AD: _dlerror_run (dlerror.c:138)
==23097==    by 0x5141747: dlopen_implementation (dlopen.c:71)
==23097==    by 0x5141747: dlopen@@GLIBC_2.34 (dlopen.c:81)
==23097==    by 0x4A36446: TROOT::InitInterpreter() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A3660E: ROOT::Internal::GetROOT2() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A4388C: TApplication::TApplication(char const*, int*, char**, void*, int) (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x486F45F: TRint::TRint(char const*, int*, char**, void*, int, bool, bool) (in /.../root_v6.26.04/lib/libRint.so.6.26.04)
==23097==    by 0x1092E6: main (in /.../root_v6.26.04/bin/root.exe)
==23097==  Address 0x54f9761 is 17 bytes inside a block of size 23 alloc'd
==23097==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==23097==    by 0x40271FF: malloc (rtld-malloc.h:56)
==23097==    by 0x40271FF: strdup (strdup.c:42)
==23097==    by 0x4008594: decompose_rpath (dl-load.c:629)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:696)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:677)
==23097==    by 0x400ABF5: _dl_map_object (dl-load.c:2165)
==23097==    by 0x4003494: openaux (dl-deps.c:64)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x4003C7B: _dl_map_object_deps (dl-deps.c:248)
==23097==    by 0x400EA0E: dl_open_worker_begin (dl-open.c:592)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400DF99: dl_open_worker (dl-open.c:782)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400E34D: _dl_open (dl-open.c:883)
==23097==    by 0x51416BB: dlopen_doit (dlopen.c:56)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x5225CF2: _dl_catch_error (dl-error-skeleton.c:227)
==23097==    by 0x51411AD: _dlerror_run (dlerror.c:138)
==23097==    by 0x5141747: dlopen_implementation (dlopen.c:71)
==23097==    by 0x5141747: dlopen@@GLIBC_2.34 (dlopen.c:81)
==23097==    by 0x4A36446: TROOT::InitInterpreter() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A3660E: ROOT::Internal::GetROOT2() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A4388C: TApplication::TApplication(char const*, int*, char**, void*, int) (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x486F45F: TRint::TRint(char const*, int*, char**, void*, int, bool, bool) (in /.../root_v6.26.04/lib/libRint.so.6.26.04)
==23097==    by 0x1092E6: main (in /.../root_v6.26.04/bin/root.exe)
==23097== 
==23097== Invalid read of size 8
==23097==    at 0x40286C8: strncmp (strcmp.S:172)
==23097==    by 0x400668D: is_dst (dl-load.c:216)
==23097==    by 0x4007F79: _dl_dst_substitute (dl-load.c:295)
==23097==    by 0x40082B7: fillin_rpath.isra.0 (dl-load.c:483)
==23097==    by 0x4008602: decompose_rpath (dl-load.c:654)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:696)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:677)
==23097==    by 0x400ABF5: _dl_map_object (dl-load.c:2165)
==23097==    by 0x4003494: openaux (dl-deps.c:64)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x4003C7B: _dl_map_object_deps (dl-deps.c:248)
==23097==    by 0x400EA0E: dl_open_worker_begin (dl-open.c:592)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400DF99: dl_open_worker (dl-open.c:782)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400E34D: _dl_open (dl-open.c:883)
==23097==    by 0x51416BB: dlopen_doit (dlopen.c:56)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x5225CF2: _dl_catch_error (dl-error-skeleton.c:227)
==23097==    by 0x51411AD: _dlerror_run (dlerror.c:138)
==23097==    by 0x5141747: dlopen_implementation (dlopen.c:71)
==23097==    by 0x5141747: dlopen@@GLIBC_2.34 (dlopen.c:81)
==23097==    by 0x4A36446: TROOT::InitInterpreter() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A3660E: ROOT::Internal::GetROOT2() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A4388C: TApplication::TApplication(char const*, int*, char**, void*, int) (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x486F45F: TRint::TRint(char const*, int*, char**, void*, int, bool, bool) (in /.../root_v6.26.04/lib/libRint.so.6.26.04)
==23097==    by 0x1092E6: main (in /.../root_v6.26.04/bin/root.exe)
==23097==  Address 0x54f9761 is 17 bytes inside a block of size 23 alloc'd
==23097==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==23097==    by 0x40271FF: malloc (rtld-malloc.h:56)
==23097==    by 0x40271FF: strdup (strdup.c:42)
==23097==    by 0x4008594: decompose_rpath (dl-load.c:629)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:696)
==23097==    by 0x400ABF5: cache_rpath (dl-load.c:677)
==23097==    by 0x400ABF5: _dl_map_object (dl-load.c:2165)
==23097==    by 0x4003494: openaux (dl-deps.c:64)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x4003C7B: _dl_map_object_deps (dl-deps.c:248)
==23097==    by 0x400EA0E: dl_open_worker_begin (dl-open.c:592)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400DF99: dl_open_worker (dl-open.c:782)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x400E34D: _dl_open (dl-open.c:883)
==23097==    by 0x51416BB: dlopen_doit (dlopen.c:56)
==23097==    by 0x5225C27: _dl_catch_exception (dl-error-skeleton.c:208)
==23097==    by 0x5225CF2: _dl_catch_error (dl-error-skeleton.c:227)
==23097==    by 0x51411AD: _dlerror_run (dlerror.c:138)
==23097==    by 0x5141747: dlopen_implementation (dlopen.c:71)
==23097==    by 0x5141747: dlopen@@GLIBC_2.34 (dlopen.c:81)
==23097==    by 0x4A36446: TROOT::InitInterpreter() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A3660E: ROOT::Internal::GetROOT2() (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x4A4388C: TApplication::TApplication(char const*, int*, char**, void*, int) (in /.../root_v6.26.04/lib/libCore.so.6.26.04)
==23097==    by 0x486F45F: TRint::TRint(char const*, int*, char**, void*, int, bool, bool) (in /.../root_v6.26.04/lib/libRint.so.6.26.04)
==23097==    by 0x1092E6: main (in /.../root_v6.26.04/bin/root.exe)
==23097== 

==23097== 
==23097== HEAP SUMMARY:
==23097==     in use at exit: 40,465,757 bytes in 14,492 blocks
==23097==   total heap usage: 136,771 allocs, 122,279 frees, 153,357,195 bytes allocated
==23097== 
==23097== LEAK SUMMARY:
==23097==    definitely lost: 0 bytes in 0 blocks
==23097==    indirectly lost: 0 bytes in 0 blocks
==23097==      possibly lost: 220,804 bytes in 174 blocks
==23097==    still reachable: 522,472 bytes in 4,139 blocks
==23097==                       of which reachable via heuristic:
==23097==                         multipleinheritance: 18,136 bytes in 8 blocks
==23097==         suppressed: 39,722,481 bytes in 10,179 blocks
==23097== Rerun with --leak-check=full to see details of leaked memory
==23097== 
==23097== For lists of detected and suppressed errors, rerun with: -s
==23097== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 184 from 43)

Could you post the report from valgrind? (I need to see the backtrace - it sounds as if your libc does things that vagrind doesn’t like)

Backtrace added.

Thank you very much for all your replies.

When I run the following command:
valgrind --suppressions=/etc/root/valgrind-root.supp /usr/bin/root.exe -q -l

The output I get :

HEAP SUMMARY:
    in use at exit: 24,302,753 bytes in 30,311 blocks
    total heap usage: 95,833 allocs, 65,522 frees, 60,383,494 bytes allocated
LEAK SUMMARY:
    definitely lost: 16 bytes in 1 blocks
    indirectly lost: 32 bytes in 1 blocks
    possibly lost: 23,815,191 bytes in 26,189 blocks
    still reachable: 476,983 bytes in 3,978 blocks
        of which reachable via heuristic:
                stdstring          : 40 bytes in 1 blocks
                 multipleinheritance: 17,856 bytes in 8 blocks
  suppressed: 10,531 bytes in 142 blocks
 ERROR SUMMARY: 115 errors from 43 contexts (suppressed: 0 from 0)

Here is the total backtrace:
erreur valgrind.txt (49.6 KB)

Now, when I run this command :

valgrind --suppressions=$(root-config --etcdir)/valgrind-root.supp $(root-config --bindir)/root.exe -q -l

I get this backtrace:

$ valgrind --suppressions=$(root-config --etcdir)/valgrind-root.supp $(root-config --bindir)/root.exe -q -l

==2085== Memcheck, a memory error detector

==2085== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

==2085== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info

==2085== Command: /usr/bin/root.exe -q -l

==2085== 



==2085== 

==2085== HEAP SUMMARY:

==2085==     in use at exit: 24,302,753 bytes in 30,311 blocks

==2085==   total heap usage: 95,846 allocs, 65,535 frees, 60,384,096 bytes allocated

==2085== 

==2085== LEAK SUMMARY:

==2085==    definitely lost: 16 bytes in 1 blocks

==2085==    indirectly lost: 32 bytes in 1 blocks

==2085==      possibly lost: 9,821,877 bytes in 7,967 blocks

==2085==    still reachable: 476,983 bytes in 3,978 blocks

==2085==                       of which reachable via heuristic:

==2085==                         stdstring          : 40 bytes in 1 blocks

==2085==                         multipleinheritance: 17,856 bytes in 8 blocks

==2085==         suppressed: 14,003,845 bytes in 18,364 blocks

==2085== Rerun with --leak-check=full to see details of leaked memory

==2085== 

==2085== For counts of detected and suppressed errors, rerun with: -v

==2085== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 115 from 43)

With no error displayed in the terminal this time …

@CorentinH Only 115 errors? You are really lucky.
ROOT 6.20/08 on Centos 7 / x86_64 / GCC 4.8.5 gives me (no “lost” bytes):
==24913== ERROR SUMMARY: 10569 errors from 5 contexts (suppressed: 112 from 43)

Well, your two backtrace outputs suggest that you have two ROOT versions “mixed”.
Check:
root-config --version
root-config --bindir # /usr/bin
root-config --libdir # /usr/lib
root-config --etcdir # /etc/root

@Wile_E_Coyote

$ root-config --version
6.20/04

$ root-config --libdir
/usr/lib

$ root-config --etcdir
/usr/etc

$ root-config --bindir
/usr/bin

So, where does “/etc/root” come from?
Try:
dpkg -S /etc/root/valgrind-root.supp