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