Not understood mem leak with TMatrix construction

Hello again

I keep on doing the cleaning of my code and I don’t understand another error given by valgrind when consruction a TMatrix with operator= or by copy-construction.
Here is an MWE

#include "TMatrixD.h"

int main(void)
{

  TMatrixD mat(3,3);
  mat(1,1)=1; mat(0,0)=1; mat(2,2)=1;

  TMatrixD mat_equal = mat;
  TMatrixD mat_const(mat);
  
}

with the command line

g++ -g -o pouet MemoryMat.C -I${ROOTSYS}/include -L${ROOTSYS}/lib -lCore -lMatrix && valgrind --suppressions=${ROOTSYS}/etc/valgrind-root.supp  --leak-check=full ./pouet

and the output of valgrind

==29308== Conditional jump or move depends on uninitialised value(s)
==29308==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==29308==    by 0x55E2C20: TMatrixT<double>::operator=(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==29308==    by 0x55E2D98: TMatrixT<double>::TMatrixT(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==29308==    by 0x403748: main (MemoryMat.C:9)
==29308== 
==29308== Conditional jump or move depends on uninitialised value(s)
==29308==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==29308==    by 0x55E2C20: TMatrixT<double>::operator=(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==29308==    by 0x55E2D98: TMatrixT<double>::TMatrixT(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==29308==    by 0x403761: main (MemoryMat.C:10)
==29308== 
==29308== 
==29308== HEAP SUMMARY:
==29308==     in use at exit: 1,665,169 bytes in 18,470 blocks
==29308==   total heap usage: 39,325 allocs, 20,855 frees, 3,596,454 bytes allocated
==29308== 
==29308== 34 bytes in 1 blocks are possibly lost in loss record 8,181 of 15,668
==29308==    at 0x4A07117: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==29308==    by 0x35038CF258: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.21)
==29308==    by 0x35038CF376: ??? (in /usr/lib64/libstdc++.so.6.0.21)
==29308==    by 0x35038D10F5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.21)
==29308==    by 0x5AC0B87: G__add_setup_func (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x5A2572B: G__pragma (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x5A8AC59: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x59D228D: G__loadfile (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x59D2A19: G__include_file (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x5A8FE9C: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x5B1862A: G__define_struct (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308==    by 0x5A8FA83: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==29308== 
==29308== LEAK SUMMARY:
==29308==    definitely lost: 0 bytes in 0 blocks
==29308==    indirectly lost: 0 bytes in 0 blocks
==29308==      possibly lost: 34 bytes in 1 blocks
==29308==    still reachable: 1,331,490 bytes in 15,428 blocks
==29308==         suppressed: 333,645 bytes in 3,041 blocks
==29308== Reachable blocks (those to which a pointer was found) are not shown.
==29308== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==29308== 
==29308== For counts of detected and suppressed errors, rerun with: -v
==29308== Use --track-origins=yes to see where uninitialised values come from
==29308== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 441 from 20)

Sorry to bother you again
thanks in advance
jbb

Sorry i forgot to mention that it was still using 5.34.32
regards
jbb

Testig the TVectorD i found the exact same behaviour.

the code is attached and the the log is here :

==19242== Conditional jump or move depends on uninitialised value(s)
==19242==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==19242==    by 0x55E2C20: TMatrixT<double>::operator=(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x55E2D98: TMatrixT<double>::TMatrixT(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x403CD8: main (MemoryMat.C:10)
==19242== 
==19242== Conditional jump or move depends on uninitialised value(s)
==19242==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==19242==    by 0x55E2C20: TMatrixT<double>::operator=(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x55E2D98: TMatrixT<double>::TMatrixT(TMatrixT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x403CF1: main (MemoryMat.C:11)
==19242== 
==19242== Conditional jump or move depends on uninitialised value(s)
==19242==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==19242==    by 0x560048D: TVectorT<double>::operator=(TVectorT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x560055B: TVectorT<double>::TVectorT(TVectorT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x403D3E: main (MemoryMat.C:16)
==19242== 
==19242== Conditional jump or move depends on uninitialised value(s)
==19242==    at 0x4DFF375: TObject::operator=(TObject const&) (in /export/home/jb232551/root_v5.34.32/lib/libCore.so.5.34)
==19242==    by 0x560048D: TVectorT<double>::operator=(TVectorT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x560055B: TVectorT<double>::TVectorT(TVectorT<double> const&) (in /export/home/jb232551/root_v5.34.32/lib/libMatrix.so.5.34)
==19242==    by 0x403D57: main (MemoryMat.C:17)
==19242== 
==19242== 
==19242== HEAP SUMMARY:
==19242==     in use at exit: 1,665,169 bytes in 18,470 blocks
==19242==   total heap usage: 39,325 allocs, 20,855 frees, 3,596,454 bytes allocated
==19242== 
==19242== 34 bytes in 1 blocks are possibly lost in loss record 8,181 of 15,668
==19242==    at 0x4A07117: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==19242==    by 0x35038CF258: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.21)
==19242==    by 0x35038CF376: ??? (in /usr/lib64/libstdc++.so.6.0.21)
==19242==    by 0x35038D10F5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.21)
==19242==    by 0x5AC0B87: G__add_setup_func (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x5A2572B: G__pragma (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x5A8AC59: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x59D228D: G__loadfile (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x59D2A19: G__include_file (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x5A8FE9C: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x5B1862A: G__define_struct (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242==    by 0x5A8FA83: G__exec_statement (in /export/home/jb232551/root_v5.34.32/lib/libCint.so.5.34)
==19242== 
==19242== LEAK SUMMARY:
==19242==    definitely lost: 0 bytes in 0 blocks
==19242==    indirectly lost: 0 bytes in 0 blocks
==19242==      possibly lost: 34 bytes in 1 blocks
==19242==    still reachable: 1,331,490 bytes in 15,428 blocks
==19242==         suppressed: 333,645 bytes in 3,041 blocks
==19242== Reachable blocks (those to which a pointer was found) are not shown.
==19242== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==19242== 
==19242== For counts of detected and suppressed errors, rerun with: -v
==19242== Use --track-origins=yes to see where uninitialised values come from
==19242== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 442 from 21)

MemoryMat.C (272 Bytes)

Many thanks and sorry for the large amount of questions lately
A bientot
jbb

Hi,

The only possible leak reported in this valgrind log is the one related to G__add_setup_func, which is not a leak (i.e. false positive per se that needs to be added to the suppression file).

The warning/error you see are problem with ‘unitialize’ read that are likely to be a know idiosyncrasy of the ROOT code that also need to be added to the suppression file.

Thanks,
Philippe.

PS. I just realized that you are still using v5, is it possible for you to start using v6? I have been addressing the issue in the master and would prefer to not have to back-port them to v5 unless it is absolutely necessary (v5 is in '‘fix-only-blockers’ mode).

Oki, thanks

I’ll add these in our own suppression file for the moment. We’ll be moving to v6 within the year i guess so it should be good quite soon. Thanks again.

Did you had a chance to look at the final one I posted on the other thread ? about the TTree::GetEntries method when passing a selection char* ?

Not understood mem leak with TTree::Draw

(Sorry for multiplying the thread)
Thanks again
cheers
jbb

Hi JBB,

Not yet :slight_smile:

Cheers,
Philippe.