Memory leak on canvas->Update()

Hi,

I have an online plotter doing canvas->Update() at 20Hz in a TThread. I observe a huge memory leak that I can only stop by commenting out canvas->Update().

This happens to me with ROOT-6.06.04, ROOT-6.06.08 and ROOT-6.08.00. I haven’t tried other versions.

[color=#00C000]SOLVED: It does work properly with ROOT-6.08.00. I didn’t properly link to that version during my tests. Thanks to all people that have answered[/color]

I’ve removed all unnecessary code while still observing the problem and now I have a code that doesn’t draw anything but still has the leak.

Essentially: I create a TApplication, a TCanvas and I do canvas->Update() at 20Hz. At this speed I loose free memory at 1 MB/s or about 53 kB/update.

The code is so simple I will just paste it here.

#include <TApplication.h>
#include <TCanvas.h>
#include <TThread.h>

void *updater(void *c) {
  TCanvas *canvas=(TCanvas*)c;
  while (1) {
    canvas->Update();
    usleep(50000); // 50000us = ~20Hz
  }
  return NULL;
}

int main(int argc, char **argv) {
  TApplication *app=new TApplication("app",0,NULL);
  TCanvas *canvas=new TCanvas("leak","leaky canvas",600,900);
  TThread *updater_t=new TThread("updater_thread",updater,(void*)canvas);
  updater_t->Run();
  app->Run();
  return 0;
}

Compile it with

I’ve also tested launching app->Run() in a POSIX thread and after that running the updater TThread. The result is the same.

Is this a bug in ROOT or am I doing something wrong?

Your code is simple … Nothing wrong it seems. We will check.

Your code snippet crashes for me after 1-2 seconds.

For the record, attached is what valgrind reports, for Ubuntu 16.04 and ROOT6 master branch.

valgrind --suppressions=$ROOTSYS/etc/valgrind-root.supp --leak-check=full --log-file="valgrindOUT.txt" ./example
./example 

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================

Thread 2 (Thread 0x7f51b9e13700 (LWP 16859)):
#0  0x00007f51d0e4151b in __GI___waitpid (pid=16862, stat_loc=stat_loc
entry=0x7f51b9e0af40, options=options
entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:29
#1  0x00007f51d0dbafbb in do_system (line=<optimised out>) at ../sysdeps/posix/system.c:148
#2  0x00007f51d1e91a04 in TUnixSystem::Exec (shellcmd=<optimised out>, this=0x17384f0) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:2116
#3  TUnixSystem::StackTrace (this=0x17384f0) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:2403
#4  0x00007f51d1e9435c in TUnixSystem::DispatchSignals (this=0x17384f0, sig=kSigSegmentationViolation) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:3661
#5  <signal handler called>
#6  TList::Remove (this=this
entry=0x173f760, obj=obj
entry=0x7f51b9e0d880) at /opt/root6/root6_src/core/cont/src/TList.cxx:701
#7  0x00007f51d1e137ae in THashList::Remove (this=0x173f760, obj=0x7f51b9e0d880) at /opt/root6/root6_src/core/cont/src/THashList.cxx:289
#8  0x00007f51d1df37a5 in TObjectSpy::~TObjectSpy (this=0x7f51b9e0d880, __in_chrg=<optimised out>) at /opt/root6/root6_src/core/base/src/TObjectSpy.cxx:56
#9  0x00007f51bb40c77a in TGFrame::HandleEvent (this=0x2ac32a0, event=<optimised out>) at /opt/root6/root6_src/gui/gui/src/TGFrame.cxx:444
#10 0x00007f51bb382e08 in TGClient::HandleEvent (this=0x292a5e0, event=0x7f51b9e0d930) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:841
#11 0x00007f51bb383125 in TGClient::ProcessOneEvent (this=0x292a5e0) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:651
#12 0x00007f51bb38318d in TGClient::HandleInput (this=0x292a5e0) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:698
#13 0x00007f51d1e94bf8 in TUnixSystem::DispatchOneEvent (this=0x17384f0, pendingOnly=<optimised out>) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:1066
#14 0x00007f51d1d84422 in TSystem::ProcessEvents (this=0x17384f0) at /opt/root6/root6_src/core/base/src/TSystem.cxx:426
#15 0x00007f51d195bd54 in TPad::WaitPrimitive (this=0x2a09da0, pname=0x2adada8 "\300\b", emode=0x2a09da0 "0[\273\321Q\177") at /opt/root6/root6_src/graf2d/gpad/src/TPad.cxx:6283
#16 0x0000000000401d33 in updater(void*) ()
#17 0x00007f51d16f4eb5 in TThread::Function (ptr=0x2adad10) at /opt/root6/root6_src/core/thread/src/TThread.cxx:812
#18 0x00007f51d04d270a in start_thread (arg=0x7f51b9e13700) at pthread_create.c:333
#19 0x00007f51d0e7c82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7f51d23b2ac0 (LWP 16839)):
#0  0x00007f51d0e729e3 in select () at ../sysdeps/unix/syscall-template.S:84
#1  0x00007f51d1e94554 in TUnixSystem::UnixSelect (nfds=<optimised out>, readready=<optimised out>, writeready=<optimised out>, timeout=<optimised out>) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:3901
#2  0x00007f51d1e94f44 in TUnixSystem::DispatchOneEvent (this=0x17384f0, pendingOnly=<optimised out>) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:1122
#3  0x00007f51d1d843a4 in TSystem::InnerLoop (this=0x17384f0) at /opt/root6/root6_src/core/base/src/TSystem.cxx:408
#4  0x00007f51d1d82edf in TSystem::Run (this=0x17384f0) at /opt/root6/root6_src/core/base/src/TSystem.cxx:358
#5  0x00007f51d1dc21ff in TApplication::Run (this=0x17a92d0, retrn=<optimised out>) at /opt/root6/root6_src/core/base/src/TApplication.cxx:1153
#6  0x0000000000401e12 in main ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum.
Only if you are really convinced it is a bug in ROOT then please submit a
report at http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#6  TList::Remove (this=this
entry=0x173f760, obj=obj
entry=0x7f51b9e0d880) at /opt/root6/root6_src/core/cont/src/TList.cxx:701
#7  0x00007f51d1e137ae in THashList::Remove (this=0x173f760, obj=0x7f51b9e0d880) at /opt/root6/root6_src/core/cont/src/THashList.cxx:289
#8  0x00007f51d1df37a5 in TObjectSpy::~TObjectSpy (this=0x7f51b9e0d880, __in_chrg=<optimised out>) at /opt/root6/root6_src/core/base/src/TObjectSpy.cxx:56
#9  0x00007f51bb40c77a in TGFrame::HandleEvent (this=0x2ac32a0, event=<optimised out>) at /opt/root6/root6_src/gui/gui/src/TGFrame.cxx:444
#10 0x00007f51bb382e08 in TGClient::HandleEvent (this=0x292a5e0, event=0x7f51b9e0d930) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:841
#11 0x00007f51bb383125 in TGClient::ProcessOneEvent (this=0x292a5e0) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:651
#12 0x00007f51bb38318d in TGClient::HandleInput (this=0x292a5e0) at /opt/root6/root6_src/gui/gui/src/TGClient.cxx:698
#13 0x00007f51d1e94bf8 in TUnixSystem::DispatchOneEvent (this=0x17384f0, pendingOnly=<optimised out>) at /opt/root6/root6_src/core/unix/src/TUnixSystem.cxx:1066
#14 0x00007f51d1d84422 in TSystem::ProcessEvents (this=0x17384f0) at /opt/root6/root6_src/core/base/src/TSystem.cxx:426
#15 0x00007f51d195bd54 in TPad::WaitPrimitive (this=0x2a09da0, pname=0x2adada8 "300b", emode=0x2a09da0 "0[273321Q177") at /opt/root6/root6_src/graf2d/gpad/src/TPad.cxx:6283
#16 0x0000000000401d33 in updater(void*) ()
#17 0x00007f51d16f4eb5 in TThread::Function (ptr=0x2adad10) at /opt/root6/root6_src/core/thread/src/TThread.cxx:812
#18 0x00007f51d04d270a in start_thread (arg=0x7f51b9e13700) at pthread_create.c:333
#19 0x00007f51d0e7c82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

===========================================================


Segmentation fault

valgrindOUT.txt (45.7 KB)

It does not crash for me (on mac with both X11 and Cocoa version) . With the cocoa version I see a small leak when canvas->Update() is present and no leak when I comment it. It is not obvious … the size of the memory used seems to stabilise after a while. With the X11 version I do not see any leak.

I used the Mac activity Monitor App to monitor the leak.

Sorry, it was a mistake of mine, mixing root5 and root6 paths, as I have both installed in the computer.
It does not crash if I stay consistent. Attached the new valgrind report.
valgrindOUT.txt (45.9 KB)

my observations (watched with top):

I see a leak with: 6.04.06 on U 14.04.5

no leak with: 6.08.01 on U 16.04.1, 6.08.00 on U 14.04.5, 5.34.34 on U 14.04.5,

Otto

Hi,

TCanvas::Update() indeed leaked in v6.04 and v6.06; but this was repaired for v6.08, as Otto confirmed. Are you certain you see a leak with v6.08, same rate? Which platform is this on?

Cheers, Axel.

I confirm the problem is solved with ROOT-6.08/00 in CentOS 7.2.1511

I guess I did not link properly against that version when testing.

Thanks for you help