bugGNU Octave - Bugs: bug #44420, Memory leaks in 4.0 RC

 
 

bug #44420: Memory leaks in 4.0 RC

Submitter:  Rik <rik5>
Submitted:  Wed 04 Mar 2015 04:51:43 AM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Performance
Status:  None Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 01 Sep 2017 07:30:34 PM UTC, comment #9: 

Closing report.  This bug was reported against the 4.0 RC which is now very out of date.  The Octave developers have also switched to ASAN for a lightweight memory checker rather than valgrind.

Rik <rik5>
Group administrator
Sat 02 Jul 2016 07:00:52 AM UTC, comment #8: 

I've looked around a bit more and I think I understand things a little better. Sorry for the noise. I found the comment in toplev.cc about "Don't call singleton_cleanup_list ..." and uncommented the cleanup call and
commented the typeinfo cleanup call:

diff -r f471f513ffd0 libinterp/corefcn/toplev.cc
--- a/libinterp/corefcn/toplev.cc        Wed Jun 29 18:50:37 2016 -0400
+++ b/libinterp/corefcn/toplev.cc        Sat Jul 02 16:17:44 2016 +1000
@@ -882,7 +882,7 @@
       // .oct files to be unregistered when the .oct file shared library
       // is unloaded.
       //
-      // OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ());
+      OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ());

       OCTAVE_SAFE_CALL (octave_chunk_buffer::clear, ());
     }
diff -r f471f513ffd0 libinterp/octave-value/ov-typeinfo.h
--- a/libinterp/octave-value/ov-typeinfo.h        Wed Jun 29 18:50:37 2016 -0400
+++ b/libinterp/octave-value/ov-typeinfo.h        Sat Jul 02 16:17:44 2016 +1000
@@ -218,7 +218,9 @@

   static octave_value_typeinfo *instance;

-  static void cleanup_instance (void) { delete instance; instance = 0; }
+  static void cleanup_instance (void) {
+    // delete instance; instance = 0;
+  }

Now "cdef_manager::cleanup_instance()" gets called.


Robert Jenssen <morgawr>
Fri 01 Jul 2016 01:16:41 AM UTC, comment #7: 

I built a debug build of the development sources with:
+verbatim
diff -r f471f513ffd0 libinterp/corefcn/Cell.h
--- a/libinterp/corefcn/Cell.h Wed Jun 29 18:50:37 2016 -0400
+++ b/libinterp/corefcn/Cell.h Fri Jul 01 11:00:59 2016 +1000
@@ -41,7 +41,7 @@
 public:
 
   Cell (void)
-    : Array<octave_value> (dim_vector (0, 0)) { }
+    : Array<octave_value> () { }
 
   Cell (const octave_value& val)
     : Array<octave_value> (dim_vector (1, 1), val) { }
-verbatim-
It passes "make check".

Most of the remaining leaks also appear to be due to reference counting in dim_vector and ArrayRep. For example valgrind shows:

==28439== 16 bytes in 1 blocks are possibly lost in loss record 706 of 1,960
==28439==    at 0x4C2C8F9: operator new[](unsigned long) (vg_replace_malloc.c:423)
==28439==    by 0x545E193: dim_vector::newrep(int) (dim-vector.h:102)
==28439==    by 0x545E363: dim_vector::dim_vector(int, int) (dim-vector.h:207)
==28439==    by 0x6970D96: Array<void*>::resize2(int, int, void* const&) (Array.cc:994)
==28439==    by 0x6971605: Array<void*>::resize(dim_vector const&, void* const&) (Array.cc:1031)
==28439==    by 0x58B178F: octave_value_typeinfo::do_register_type(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&, octave_value const&) (ov-typeinfo.cc:213)
==28439==    by 0x58B10F4: octave_value_typeinfo::register_type(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&, octave_value const&) (ov-typeinfo.cc:65)
==28439==    by 0x58A5F84: octave_struct::register_type() (ov-struct.cc:52)
==28439==    by 0x58D00E7: install_types() (ov.cc:2700)
==28439==    by 0x545D443: octave_initialize_interpreter (octave.cc:824)
==28439==    by 0x401713: main (main-cli.cc:90)

and

==28439== 8 bytes in 1 blocks are definitely lost in loss record 43 of 1,960
==28439==    at 0x4C2C8F9: operator new[](unsigned long) (vg_replace_malloc.c:423)
==28439==    by 0x5463580: Array<octave_value>::ArrayRep::ArrayRep(int) (Array.h:77)
==28439==    by 0x5461ECC: Array<octave_value>::Array(dim_vector const&, octave_value const&) (Array.h:186)
==28439==    by 0x57C774B: Cell::Cell(int, int, octave_value const&) (Cell.h:53)
==28439==    by 0x580260A: to_ov(std::__cxx11::list<cdef_class, std::allocator<cdef_class> > const&) (ov-classdef.cc:206)
==28439==    by 0x580E122: cdef_class::cdef_class_rep::cdef_class_rep(std::__cxx11::list<cdef_class, std::allocator<cdef_class> > const&) (ov-classdef.cc:1824)
==28439==    by 0x5822F2E: cdef_class::cdef_class(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::list<cdef_class, std::allocator<cdef_class> > const&) (ov-classdef.h:770)
==28439==    by 0x58069CB: make_class(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::list<cdef_class, std::allocator<cdef_class> > const&) (ov-classdef.cc:645)
==28439==    by 0x5818A68: install_classdef() (ov-classdef.cc:3417)
==28439==    by 0x545D452: octave_initialize_interpreter (octave.cc:830)
==28439==    by 0x401713: main (main-cli.cc:90)


Robert Jenssen <morgawr>
Sat 21 Mar 2015 02:17:08 AM UTC, comment #6: 

Using the valgrind log I can see that a whole slew of small 8 byte leaks are due to this code in ov-classdef.cc at line 701.


static cdef_class
make_class (const std::string& name,
            const std::list<cdef_class>& super_list = std::list<cdef_class> ())
{
  cdef_class cls (name, super_list);

  cls.set_class (cdef_class::meta_class ());
  cls.put ("Abstract", false);
  cls.put ("ConstructOnLoad", false);
  cls.put ("ContainingPackage", Matrix ());
  cls.put ("Description", std::string ());
  cls.put ("DetailedDescription", std::string ());
  cls.put ("Events", Cell ());
  cls.put ("Hidden", false);
  cls.put ("InferiorClasses", Cell ());
  cls.put ("Methods", Cell ());
  cls.put ("Properties", Cell ());
  cls.put ("Sealed", false);


Everywhere an empty Cell() object is created causes a leak.

I believe the put routine is defined at ov-classdef.h:408.


  void put (const std::string& pname, const octave_value& val)
  { map.assign (pname, val); }


Maybe when a map goes out of existence it is somehow failing to call the the destructor for the right-side value.

Rik <rik5>
Group administrator
Wed 04 Mar 2015 05:14:26 PM UTC, comment #5: 

I'm using valgrind 3.7.0.

A simpler, quicker test is


./run-octave -valgrind -f
cd test/classdef
test classdef.tst
exit


assuming that run-octave has been hacked to run octave-cli.  This completes in about 1 minute and shows leaks from classdef.

Rik <rik5>
Group administrator
Wed 04 Mar 2015 04:52:49 PM UTC, comment #4: 

OK, I'm now trying exactly the same options as you used, except for the log file because I want to see the valgrind messages mixed with the list of tests.

What version of valgrind are you using?

John W. Eaton <jwe>
Group administrator
Wed 04 Mar 2015 04:11:57 PM UTC, comment #3: 

I ran into that same problem of running valgrind on the dispatch program octave rather than on octave-cli or octave-gui.  I worked around it by editing my copy of run-octave.


  elif [ "x$1" = "x-valgrind" ]; then
    ##driver="valgrind --tool=memcheck"
    driver="valgrind -v --tool=memcheck --leak-check=yes --leak-resolution=high --num-callers=50 --log-file=valgrind.log"
    octave_executable="$builddir/src/octave-cli"
    shift



Rik <rik5>
Group administrator
Wed 04 Mar 2015 03:32:49 PM UTC, comment #2: 

Oops, wait, I think the way I was running make check made it so that I was only running valgrind on the driver program, not Octave itself.

Trying again by forcing octave-cli in the run-octave script.  Now the tests are running much slower, so I think I'm using valgrind now.  But so far no messages either.  I'll let it run and see what happens.

I guess we need a way to be able to specify both -valgrind and -cli as options for the run-octve script...

John W. Eaton <jwe>
Group administrator
Wed 04 Mar 2015 03:27:33 PM UTC, comment #1: 

I'm not seeing results that are so bad.

I tried running


make check RUN_OCTAVE_OPTIONS=-valgrind


When that was silent where you had errors, I edited the run-octave script to add --leak-check=full to the valgrind options and tried again.  I still don't see the errors you are seeing.

What version of valgrind do you have?  I'm using 1:3.10.0-4 on a Debian amd64 system.

John W. Eaton <jwe>
Group administrator
Wed 04 Mar 2015 04:51:43 AM UTC, original submission:  

See the attached file which is the output from using hg id 19894:ac18e88ea1bf under valgrind and running _run_test_suite_.

Search for "definitely lost" to find guaranteed memory leaks.

There are definitely some in the new classdef parser.

Rik <rik5>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #33242:  valgrind.log.bz2 added by rik5 (161KiB - application/x-bzip)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by morgawr (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-09-01 rik5 Open/ClosedOpen Closed
    2015-03-04 rik5 Attached File- Added valgrind.log.bz2, #33242

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code