octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #47372] Memory leaks and segmentation faults i


From: John W. Eaton
Subject: [Octave-bug-tracker] [bug #47372] Memory leaks and segmentation faults in Octave
Date: Wed, 30 Mar 2016 04:02:36 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0 Iceweasel/44.0

Follow-up Comment #62, bug #47372 (project octave):

I think I've found the reason for the crash on Windows systems.  The problem
is not the GraphicsMagick library, but the way dynamic libraries resolve
symbols on Windows systems.

In F__magick_formats__, we have


  if (! coder.isReadable ())
    fmt.setfield ("read",  Matrix ());


The empty Matrix object ultimately uses this code from Array<T>:


  typename Array<T>::ArrayRep *nil_rep (void) const
  {
    static typename Array<T>::ArrayRep nr;
    return &nr;
  }


On ELF systems when the main program and its shared libraries are linked with
-rdynamic, symbols from shared libraries that are loaded with dlopen are found
in the main program and its libraries first, so F__magick_formats__ and Octave
both use the same static NR object.  The struct that __magick_foramts__
returns is stored in Octave's symbol table.  If __magick_read__.oct (the
shared library where F__magick_formats__ is defined) is dlclosed and unloaded
before Octave cleans up the symbol table, there is no problem because the
memory for the static NR object is stored in libobctave, which is still
loaded.

But on Windows systems, the NR object is that F__magic_formats__ is using is
being initialized separately, because when __magick_read__.oct is loaded, the
symbols from liboctave are initialized again.

You can easily see this difference if you change the code in
F__magick_formats__ to be


  Matrix mtmx;
  if (! coder.isReadable ())
    fmt.setfield ("read",  mtmx);


and then examine the reference count for the rep object.  On my Debian system,
I see a count of about 300 when I call __magick_formats__ just after starting
Octave.  On Windows, it is just 2.

So the static NR symbol is not from Octave, but from the __magick_read__.oct
DLL.  When that file is closed, the pointer to NR is no longer valid.  But it
is still stored in Octave in the structure that __magick_formats__ returned,
so when Octave exits and the symbol table is cleaned up, Octave crashes when
it tries to dereference rep in the expression "if (rep->count--) ..." in the
Array destructor.

Changing the nil_rep function to do this instead:

"works".  But that's not really a general solution here, because there may be
cases where we actually must access a global variable from liboctave or
libinterp inside a DLL.  So what is the proper way to tell the Windows dynamic
linker to do this instead of binding to a second copy and/or reinitializing
the global state?

Guessing that the problem is that NR is not exported, I tried the following
change and Octave still crashed on exit, though in a slightly different
location.


diff --git a/liboctave/array/Array.cc b/liboctave/array/Array.cc
--- a/liboctave/array/Array.cc
+++ b/liboctave/array/Array.cc
@@ -2770,6 +2770,10 @@ void Array<T>::instantiation_guard ()
   T::__xXxXx__ ();
 }
 
+template <class T>
+typename Array<T>::ArrayRep
+Array<T>::nil_rep_obj;
+
 #define INSTANTIATE_ARRAY(T, API) \
   template <> void Array<T>::instantiation_guard () { } \
   template class API Array<T>
diff --git a/liboctave/array/Array.h b/liboctave/array/Array.h
--- a/liboctave/array/Array.h
+++ b/liboctave/array/Array.h
@@ -149,14 +149,15 @@ protected:
 
 private:
 
+  static typename Array<T>::ArrayRep nil_rep_obj;
+
   typename Array<T>::ArrayRep *nil_rep (void) const
   {
     // NR was originally allocated with new, but that does not seem
     // to be necessary since it will never be deleted.  So just use
     // a static object instead.
 
-    static typename Array<T>::ArrayRep nr;
-    return &nr;
+    return &nil_rep_obj;
   }
 
 protected:



    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?47372>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]