openexr-user
[Top][All Lists]
Advanced

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

[Openexr-user] IlmThread is not DSO safe for static builds


From: Gonzalo Garramuño
Subject: [Openexr-user] IlmThread is not DSO safe for static builds
Date: Fri, 14 Dec 2007 07:23:41 -0300
User-agent: Thunderbird 2.0.0.6 (X11/20071022)


On posix mainly (windows should be okay). The problem does not effect DSO builds and linking of the library.

Now, before you ask why I need to link statically, the reason is that multiple vendors ship older (and sometimes unknown) versions of OpenEXR and the OpenEXR library has, unfortunately, not kept binary compatibility between releases. Exposing the symbols (on posix mainly) creates all sorts of crashes.

Anyway, back to the static linking issue.  The problem is this:

a) IlmThreadPoolPosix.cpp creates a global like:
        ThreadPool gThreadPool (0);
b) IlmThreadPool's destructor tries to acquire a lock on one of its mutex member variables, which are are *not* allocated with new.

When multiple DSOs link against the library statically, the result is that the gThreadPool's data is instantiated multiple times.


Here's an example of two shaders statically linking to the library (thru IlmImf, actually):

mental ray: mrLibrary: module_init end
mental ray: Registering 2008-x64 mrLiquid 0.8.0.0 shaders
ThreadPool::Data::Data 0x3eecf70
ThreadPool 0x2aaab2f6cbd0
ThreadPool::Data::Data 0x3ef0b70
ThreadPool 0x2aaab2f6cbd0
mental ray: Registering 2008-x64 mrLiquid 0.8.0.0 shaders done
mental ray: mrLibrary: module already inited - no globals reinited
mental ray: mrLibrary: module already inited - no globals reinited

As you can see, the compiler/dso loader is smart to create only one instance of ThreadPool, but two ThreadPool::Data are *still* initialized, regardless (don't ask me -- seems more like a gcc bug to me). This already leaves a memory leak.


On exit, this is what happens:

mental ray: mrLibrary: module_exit start
mental ray: mrLibrary: No memory leaks detected.
mental ray: mrLibrary: module_exit end
~ThreadPool 0x2aaab2f6cbd0
ThreadPool::Data::~Data 0x3ef0b70
~ThreadPool 0x2aaab2f6cbd0
ThreadPool::Data::~Data 0x3ef0b70
terminate called after throwing an instance of 'Iex::EinvalExc'
  what():  Cannot lock mutex (Invalid argument).

The ThreadPool is deleted twice, leading to an exception as the mutex has already been destroyed once.


So my suggestions is:
- Eliminate the gThreadPool global and make it a pointer inited to NULL and initialize the pointer as needed. That's safe to use on a static library.




--
Gonzalo Garramuño
address@hidden

AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy




reply via email to

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