[osg-users] OpenSceneGraph-3.6.5 release candidate 2 tagged, please test

OpenSceneGraph Users osg-users at lists.openscenegraph.org
Tue Jan 28 01:11:23 PST 2020


Hi Fabian,


> My build is using static osg, static osg-plugins and link time
> optimization.
> I created an address sanitizer enabled build.
> It exhibits a heap-use-after-free.
> I will try to further investigate this week.
>
> =================================================================
> ==11872==ERROR: AddressSanitizer: heap-use-after-free on address
> 0x6030000082c0 at pc 0x55b4b9659551 bp 0x7ffdf8a9c190 sp 0x7ffdf8a9c180
> READ of size 8 at 0x6030000082c0 thread T0
>     #0 0x55b4b9659550 in
> OpenThreads::ScopedPointerLock<OpenThreads::Mutex>::ScopedPointerLock(OpenThreads::Mutex*)
> ./openmw/extern-git/OpenSceneGraph/include/OpenThreads/ScopedLock:54
>     #1 0x55b4b9659550 in osg::StateAttribute::removeParent(osg::StateSet*)
> ./openmw/extern-git/OpenSceneGraph/src/osg/StateAttribute.cpp:38
>     #2 0x55b4b965a033 in osg::StateSet::clear()
> ./openmw/extern-git/OpenSceneGraph/src/osg/StateSet.cpp:734
>

Given the stack trace it kinda looks like the getRefMutex() call in
StateAttribute.cpp is the where things might be going astray (note the
comment I've added below):

void StateAttribute::removeParent(osg::StateSet* object)
{
    OpenThreads::ScopedPointerLock<OpenThreads::Mutex> lock(getRefMutex());
// calls the base classes Referenced::getRefMutex() method that will map to
Referenced::getGlobalReferencedMutex

    ParentList::iterator pitr =
std::find(_parents.begin(),_parents.end(),object);
    if (pitr!=_parents.end()) _parents.erase(pitr);
}

The Referenced::getGlobalReferencedMutex() implementation in Referenced.cpp
is:

OpenThreads::Mutex* Referenced::getGlobalReferencedMutex()
{
    static GlobalMutexPointer s_ReferencedGlobalMutext = new
OpenThreads::Mutex;
    return s_ReferencedGlobalMutext.get();
}

// helper class for forcing the global mutex to be constructed when the
library is loaded.
struct InitGlobalMutexes
{
    InitGlobalMutexes()
    {
        Referenced::getGlobalReferencedMutex();
    }
};
static InitGlobalMutexes s_initGlobalMutexes;

Which is all a bit hacky way of trying to get a singleton's
_ReferencedGlobalMutext to construct before any other code calling
getGlobalReferencedMutex() gets called.

I don't really know why a pointer is even being used here, it's not how I'd
write the code these days, but off the top of my head don't recall the
derivation and motivations between all this code as it dates back to the
earliest days of the OSG project, so almost two decades :-)

What I'd write today would simply be:

static OpenThreads::Mutex s_ReferencedGlobalMutex;
OpenThreads::Mutex* Referenced::getGlobalReferencedMutex()
{
    return &s_ReferencedGlobalMutex;
}

You could try substituting this in.  I will try a build here just to make
sure the above works fine for standard OSG work.  I don't expect this
change to have any affect on your own code, if it does it suggest there is
some issue with order of clean up of statics.

Robert.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20200128/02ec9e5d/attachment.html>


More information about the osg-users mailing list