bugGNU Octave - Bugs: bug #34195, Inconsistency detected by ld.so:...

 
 

bug #34195: Inconsistency detected by ld.so: dl-close.c: 736: _dl_close: Assertion `map->l_init_called' failed!

Submitter:  Colin Watson <cjwatson>
Submitted:  Fri 02 Sep 2011 12:44:12 PM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * 3.2.4 Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 13 Sep 2011 11:31:46 AM UTC, comment #3: 

What sort of binary compatibility are you expecting with previous releases?  If you just want code compiled and linked with the old library to be able to use the new one, then I think you are OK since the changes you are making just add a static method (no virtual functions are involved).  What does marking the function as hidden do?  Does it prevent code from outside liboctinterp from using the new function?  If so, I guess I don't see how that could hurt, but I don't think it is necessary in this case unless you want to prevent someone else from using that function and then trying to link their newly compiled code with an old library version.

John W. Eaton <jwe>
Group administrator
Thu 08 Sep 2011 12:14:08 PM UTC, comment #2: 

Indeed, you're right that the current development sources from Mercurial don't exhibit this problem.  Thanks for pointing that out.

We can't easily upgrade right now (we're pretty late in our six-month release cycle), so I investigated a bit to try to find the specific fix; also since I've seen several other people asking about it so it would be good to have a solution that turns up on search engines.  As it turned out, it was exactly the approach I suggested of clearing the symbol table:

  http://hg.savannah.gnu.org/hgweb/octave/rev/9981
  http://hg.savannah.gnu.org/hgweb/octave/rev/9992

I'll backport that pair of changes, since they're pretty well-contained.  To avoid shipping a liboctinterp with a different ABI than other systems, I plan to temporarily add _attribute_ ((visibility ("hidden"))) to the declaration of symbol_table::cleanup in the backport patch.  If that sounds insane, please shout!

Colin Watson <cjwatson>
Fri 02 Sep 2011 04:37:56 PM UTC, comment #1: 

I can't duplicate this with the current stable release of Octave  (3.4.2) on my Debian system.  I think there were some significant changes in the way Octave loads and manages .oct files going from 3.2.4 to 3.4.2.  If you can duplicate the error with the current stable release or the current development sources, I'd be interested in trying to fix the problem.  Otherwise, I think the problem has already been fixed and I would recommend upgrading.

John W. Eaton <jwe>
Group administrator
Fri 02 Sep 2011 12:44:12 PM UTC, original submission:  

Octave's dynamic library handling sometimes manages to tickle an assertion in GNU libc's dynamic linker.  I've seen this reported in a few places, for example:

  https://bugs.launchpad.net/ubuntu/+source/octave-symbolic/+bug/831157
  http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=633719
  http://comments.gmane.org/gmane.comp.programming.swig.devel/20631
  http://comments.gmane.org/gmane.comp.gnu.octave.bugs/16976

However, nothing I've found seems to provide a resolution so far, so I've been spending some time digging into this as part of the general quest to make every source package in Ubuntu actually build cleanly.

In the last of the URLs above, Xavier Delacour provides a test case, and comments:

  "Glancing at sources (fetched with apt-get source on that system), the direct problem is that dlclose is called on the shared library that has been marked with RTLD_NODELETE (eglibc/elf/dl-close:734). That flag can be set via dlopen (Octave doesn't do this), as well as under certain circumstances internal to glibc. One of those is when STB_GNU_UNIQUE symbols ("u" in nm [3]) are loaded in the oct-file"

I have some information to add to that.  The assertion that's directly being tripped here is that the shared object being closed is in an initialised state.  This means that (a) it has been opened at some point (which is true here) and (b) that it has not been finalised.  There are two ways a dynamically-loaded shared object can be finalised: one is dlclose, but the other is as part of the general finalisation that happens on process exit (_dl_fini).  On exit, dynamically-loaded shared object are finalised in reverse dependency order, that is, each object is finalised before any of the objects it depends on.

In the case I'm working on, symbols.oct from the octave-symbolic package depends on liboctinterp.so.  ld.so therefore finalises symbols.oct first (setting l_init_called to 0 along the way).  Later, it attempts to finalise liboctinterp.so.  This goes through the usual C++ process of finalising all allocated objects, including the symbol table.  In the process it finds the reference it's still holding to symbols.oct and calls octave_dld_function::~octave_dld_function on it, which ultimately ends up calling dlclose on this shared object that's already been finalised.  The environment variable LD_DEBUG=all was helpful in diagnosing this; it shows:

     22029:     calling fini: /tmp/buildd/octave-symbolic-1.0.9/debian/octave-symbolic/usr/lib/octave/packages/3.2/symbolic-1.0.9/i686-pc-linux-gnu-api-v37/symbols.oct [0]
     22029:     calling fini: /tmp/buildd/liboctave/liboctinterp.so [0]

... followed shortly after by the assertion failure.

I'm sure Xavier is right that certain symbol types are needed to trigger this particular path through _dl_close, although I haven't done any investigation of that myself.  However, I think that in any case an attempt to finalise a shared object twice is clearly a bug.  It is possible that this is in fact a dynamic linker bug of sorts: shouldn't it avoid finalising shared objects with a non-zero dlopen reference count?

However, I think it's possible for Octave to work around this.  If do_octave_atexit were careful to close any open shared objects (perhaps by finalising all symbol tables?) before falling through to ::exit, then it seems to me that it would reliably avoid this assertion failure.

I don't know Octave well enough to make a guess at the best way to do this.  I'm happy to have a stab at it given a few pointers, or to test suggested fixes.

Colin Watson <cjwatson>

 

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

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by cjwatson (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
    2011-09-13 jwe StatusNone Fixed
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code