Hi Robert,

It is hard to reproduce this problem (as any thread safety problem) in same state as previous.

I have another crash with same problem at:
ntdll!RtlEnterCriticalSection+0x6
ot12_OpenThreads!OpenThreads::Mutex::lock+0xe
osgdb_deprecated_osg!initGLNames+0x66
osgdb_deprecated_osg!StateSet_readLocalData+0x4f
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObjectOfType+0x9eb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObjectOfType+0x28
osgdb_deprecated_osg!Node_readLocalData+0x349
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_osg!OSGReaderWriter::readNode+0xfe
osgdb_osg!OSGReaderWriter::readNode+0x31c
osg80_osgDB!osgDB::Registry::ReadNodeFunctor::doRead+0x28
osg80_osgDB!osgDB::Registry::read+0x5e4
osg80_osgDB!osgDB::Registry::readImplementation+0x34c
osg80_osgDB!osgDB::Registry::readNodeImplementation+0x6a
osg80_osgDB!osgDB::Registry::readNode+0xfc
osg80_osgDB!osgDB::readNodeFile+0x4e

crashed code:
int Mutex::lock() {
    Win32MutexPrivateData *pd =
        static_cast<Win32MutexPrivateData*>(_prvData);

#ifdef USE_CRITICAL_SECTION

    // Block until we can take this lock.
    EnterCriticalSection( &(pd->_cs) ); <<<<<<<<<<<< CRASH HERE

    return 0;
[...]

pd->_cs == NULL

in this case problem at
void initGLNames()
{
    static bool first_time = true;
    if (!first_time) return;

    static OpenThreads::Mutex s_initGLNames;
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_initGLNames);

[...]

There is lot of other places with same design:
AnimationPath.cpp:201: static osg::ref_ptr<osg::AnimationPath> s_path = new osg::AnimationPath; CoordinateSystemNode.cpp:48: static ref_ptr<EllipsoidModel> s_ellipsoidModel = new EllipsoidModel; Drawable.cpp:30: static ref_ptr<StateSet> s_drawstate = new osg::StateSet;
Node.cpp:77:    static ref_ptr<StateSet> s_drawstate = new osg::StateSet;
Node.cpp:85: static ref_ptr<NodeCallback> s_nodecallback = new osg::NodeCallback; NodeCallback.cpp:31: static osg::ref_ptr<NodeCallback> s_nc = new NodeCallback; OccluderNode.cpp:30: static ref_ptr<ConvexPlanarOccluder> s_occluder = new ConvexPlanarOccluder;
Sequence.cpp:26:static bool Sequence_matchLoopMode(const char* str,
Sequence.cpp:45:static const char* Sequence_getLoopMode(Sequence::LoopMode mode)
Sequence.cpp:57:static bool Sequence_matchSeqMode(const char* str,
Sequence.cpp:76:static const char* Sequence_getSeqMode(Sequence::SequenceMode mode) StateAttribute.cpp:32: static ref_ptr<StateAttributeCallback> s_callback = new osg::StateAttributeCallback;
StateSet.cpp:80:    static bool first_time = true;
StateSet.cpp:83:    static OpenThreads::Mutex s_initGLNames;
StateSet.cpp:362: static ref_ptr<StateSet::Callback> s_callback = new osg::StateSet::Callback; Uniform.cpp:212: static ref_ptr<Uniform::Callback> s_callback = new osg::Uniform::Callback;

Mikhail.

04.06.2012 12:44, Robert Osfield написал:
Hi Mikhail,

I have moved the static into the global scope of the
osgWrappers/deprecated-dotosg/Drawable.cpp, file attached, could try
it out?

Robert.

On 2 June 2012 11:12, Mikhail I. Izmestev<izmmish...@gmail.com>  wrote:
Hi,

I noticed crashing in dotosg wrappers when try to use osgDB::readNodeFile
from multiple threads.
Crash occurs when I try to load .osg file from two threads.

For example callstack of crashed thread:
osg80_osgDB!concrete_wrapper::matches+0x4
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObjectOfType+0x527
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObjectOfType+0x28
osgdb_deprecated_osg!Drawable_readLocalData+0xa1
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readDrawable+0xe1
osgdb_deprecated_osg!Geode_readLocalData+0x90
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x71
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x71
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_osg!OSGReaderWriter::readNode+0xfe
osgdb_osg!OSGReaderWriter::readNode+0x31c
osg80_osgDB!osgDB::Registry::ReadNodeFunctor::doRead+0x28
osg80_osgDB!osgDB::Registry::read+0x5e4
osg80_osgDB!osgDB::Registry::readImplementation+0x34c
osg80_osgDB!osgDB::Registry::readNodeImplementation+0x6a
osg80_osgDB!osgDB::Registry::readNode+0xfc
osg80_osgDB!osgDB::readNodeFile+0x4e
[...]

second thread callstack:
msvcp90!std::basic_istream<char,std::char_traits<char>
msvcp90!std::basic_istream<char,std::char_traits<char>
osg80_osgDB!osgDB::FieldReader::_readField+0x3f8
osg80_osgDB!osgDB::FieldReaderIterator::field+0x19d
osgdb_deprecated_osg!Array_readLocalData+0xbfb
osgdb_deprecated_osg!Geometry_readLocalData+0x991
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readDrawable+0xe1
osgdb_deprecated_osg!Geode_readLocalData+0x90
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x71
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x9a
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x9a
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_deprecated_osg!Group_readLocalData+0x71
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readObject+0x8fb
osg80_osgDB!osgDB::DeprecatedDotOsgWrapperManager::readNode+0xe1
osgdb_osg!OSGReaderWriter::readNode+0xfe
osgdb_osg!OSGReaderWriter::readNode+0x31c
osg80_osgDB!osgDB::Registry::ReadNodeFunctor::doRead+0x28
osg80_osgDB!osgDB::Registry::read+0x5e4
osg80_osgDB!osgDB::Registry::readImplementation+0x34c
osg80_osgDB!osgDB::Registry::readNodeImplementation+0x6a
osg80_osgDB!osgDB::Registry::readNode+0xfc
osg80_osgDB!osgDB::readNodeFile+0x4e
[...]

code:
struct concrete_wrapper: basic_type_wrapper
{
    virtual ~concrete_wrapper() {}
    concrete_wrapper(const osg::Object *myobj) : myobj_(myobj) {}
    bool matches(const osg::Object *proto) const
    {
        return myobj_->isSameKindAs(proto);<<<<<<<<<<<<<<<<<CRASH
HERE<<<<<<<
    }
    const osg::Object *myobj_;
};

crash occurs because myobj_ is NULL.

myobj_ passed from osgdb_deprecated_osg!Drawable_readLocalData as
s_drawstate

bool Drawable_readLocalData(Object&  obj, Input&  fr)
{
    bool iteratorAdvanced = false;

    Drawable&  drawable = static_cast<Drawable&>(obj);

    static ref_ptr<StateSet>  s_drawstate = new osg::StateSet;
    if (StateSet* readState =
static_cast<StateSet*>(fr.readObjectOfType(*s_drawstate)))
    {
        drawable.setStateSet(readState);
        iteratorAdvanced = true;
    }
[...]


so problem is in
    static ref_ptr<StateSet>  s_drawstate = new osg::StateSet;

MSVC 2008 x64 compiler (maybe gcc too) generate this code as:

static bool s_drawstate_init = false;
static ref_ptr<StateSet>  s_drawstate = NULL;

bool Drawable_readLocalData(Object&  obj, Input&  fr)
{
    bool iteratorAdvanced = false;

    Drawable&  drawable = static_cast<Drawable&>(obj);

    if(!s_drawstate_init)
    {
        s_drawstate_init = true;
        s_drawstate = new osg::StateSet;
    }

    if (StateSet* readState =
static_cast<StateSet*>(fr.readObjectOfType(*s_drawstate)))
    {
        drawable.setStateSet(readState);
        iteratorAdvanced = true;
    }
[...]


and this code is not thread safe as you can see.

Possible solution is to move static variables to global scope to avoid lazy
initialization.


Mikhail.
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to