[osg-users] Is text thread safe in 2.0.0?

Robert Osfield robert.osfield at gmail.com
Wed Sep 5 01:32:25 PDT 2007


Hi Sherman,

I don't have any ideas right now.  I will add an external load option
into the text demo multi-threaded portion and see if I can recreate
the crashes.

Robert.

On 9/5/07, sherman wilcox <wilcox.sherman at gmail.com> wrote:
> Success! Well, not that kind of success. You see, I was running the
> osgText multithreaded sample you wrote...it would not crash. Ran
> perfectly on all my systems. So......I crank up my app, which just so
> happens has an option to update osgText objects on a background
> thread. CRASH!!! Time and time again...crash! So, I spent most of the
> night trying to debug this.
>
> Long story shortened, I haven't figured out the crash BUT I have a
> clue. If I introduce an earth model built using osgDem into your
> osgText demo with about 10 threads running (probably will happen with
> fewer, haven't tried) I get the same crash as I do in my app. I
> suspect the problem has something to do with the databasepager.
>
> Let me explain. The crash in the new --MT osgText demo (as well as in
> my app) both die in:
> osgText::Font::getGlyphImageMarginRatio()  Line 241 C++
>
> Here's my call stack:
> osgText.dll!osgText::Font::getGlyphImageMarginRatio()  Line 241 C++
> > osgdb_freetype.dll!FreeTypeFont::setFontResolution(unsigned int width=60, unsigned int height=60)  Line 64 + 0x9 bytes C++
> osgText.dll!osgText::Text::computeGlyphRepresentation()  Line 485 C++
> osgText.dll!osgText::Text::setFont(osgText::Font * font=0x0828e2c8)
> Line 119 + 0x7 bytes C++
> osgText.dll!osgText::Text::setFont(const
> std::basic_string<char,std::char_traits<char>,std::allocator<char> > &
> fontfile="Arial.ttf")  Line 124 + 0x1a bytes C++
>
>
> Here's the call stack from the osgText demo:
> > osgText.dll!osgText::Font::getGlyphImageMarginRatio()  Line 241 C++
> osgdb_freetype.dll!FreeTypeFont::setFontResolution(unsigned int
> width=32, unsigned int height=32)  Line 64 + 0x9 bytes C++
> osgText.dll!osgText::Text::computeGlyphRepresentation()  Line 485 C++
> osgText.dll!osgText::Text::setText(const osgText::String & text={...})
>  Line 165 + 0x7 bytes C++
> osgText.dll!osgText::Text::setText(const
> std::basic_string<char,std::char_traits<char>,std::allocator<char> > &
> text=")]#œ<")  Line 170 + 0x1e bytes C++
> osgtest.exe!UpdateTextOperation::load()  Line 561 C++
> osgtest.exe!UpdateTextOperation::operator()(osg::Object *
> callingObject=0x00000000)  Line 498 + 0x5 bytes C++
> osg.dll!osg::OperationThread::run()  Line 416 C++
> OpenThreads.dll!OpenThreads::ThreadPrivateActions::StartThread(void *
> data=0x00f29f90)  Line 120 C++
> msvcr80.dll!__endthreadex()  + 0x3b bytes
> msvcr80.dll!__endthreadex()  + 0xc7 bytes
> kernel32.dll!@BaseThreadInitThunk at 12()  + 0xe bytes
> ntdll.dll!__RtlUserThreadStart at 8()  + 0x23 bytes
>
> They both die in osgText::Font::getGlyphImageMarginRatio().
>
> I'm wondering if there's a reference count problem somewhere that's
> causing the Font object to be prematurely deleted? That is, the
> "activeFont" object in Text::computeGlyphRepresentation is getting the
> rug pulled out from under it. I say that because the databasepager
> will call Registry::readImplementation(const ReadFunctor& readFunctor,
> bool useObjectCache)   with useObjectCache as false...which clears the
> cache which decrements the refcount on cached Font objects...sometimes
> this decrement is fatal? Maybe? I dunno, maybe I'm grasping @ straws,
> but I do know if you don't incorporate the database pager then things
> seem to run fine.
>
> Any ideas?
>
> On 9/4/07, Robert Osfield <robert.osfield at gmail.com> wrote:
> > Hi Sheman,
> >
> > Thanks for testing and changes.  I have added static Mutex directly
> > into the DefaultFont::instance() method rather that add it the
> > DefaultFont class.  It should provide the same effect but keep things
> > a little bit neater.
> >
> > I have also added a mutex into Font::GlphTexture to marshal the
> > addGlyph and texture apply.
> >
> > Could you do an svn update and let me know how you get on,
> >
> > Cheers.
> > Robert.
> >
> > On 9/2/07, sherman wilcox <wilcox.sherman at gmail.com> wrote:
> > > I spent a few moments digging into the crash I was having...looks like
> > > a race condition in DefaultFont* DefaultFont::instance(). I wasn't
> > > sure about the best course, but I thought the simplest solution was to
> > > wrap that call with a mutex, which I did. After doing that, no more
> > > crashes when I run --mt 10 in Release mode. I've attached the changes
> > > defaultfont.h/.cpp.
> > >
> > > BUT...I still get crashes in debug mode @ --mt 10 The crashes are
> > > easily reproduced. I left the code running for quite a while in
> > > Release mode, didn't crash. Debug dies immediatly.
> > >
> > >
> > > I've attached the changes defaultfont.h/.cpp.
> > >
> > >
> > > Here's a call stack from the new crashes...in void
> > > Font::GlyphTexture::apply(osg::State& state)  I noticed that the
> > > elements in the _glyphs container had bad _font objects...these _font
> > > objects had addresses of 0xcdcdcdcd. Not sure at what point things
> > > went off into the weeds.
> > >
> > > Stack trace from most recent crash:
> > >
> > > >       osgTextd.dll!std::_Vector_const_iterator<osg::ref_ptr<osgText::Font::Glyph>,std::allocator<osg::ref_ptr<osgText::Font::Glyph>
> > > > >::operator++()  Line 117 + 0x33 bytes        C++
> > >         osgTextd.dll!osgText::Font::GlyphTexture::apply(osg::State &
> > > state={...})  Line 653 + 0x8 bytes      C++
> > >         osgd.dll!osg::State::applyAttribute(const osg::StateAttribute *
> > > attribute=0x0195c730, osg::State::AttributeStack & as={...})  Line
> > > 1158 + 0x13 bytes       C++
> > >         osgd.dll!osg::State::applyTextureAttribute(unsigned int unit=0,
> > > const osg::StateAttribute * attribute=0x0195c730)  Line 337 + 0x10
> > > bytes   C++
> > >         osgTextd.dll!osgText::Text::renderOnlyForegroundText(osg::State &
> > > state={...}, const osg::Vec4f & colorMultiplier={...})  Line 1971 +
> > > 0x1d bytes      C++
> > >         osgTextd.dll!osgText::Text::drawImplementation(osg::State &
> > > state={...}, const osg::Vec4f & colorMultiplier={...})  Line 1587       C++
> > >         osgTextd.dll!osgText::Text::drawImplementation(osg::RenderInfo &
> > > renderInfo={...})  Line 1471    C++
> > >         osgd.dll!osg::Drawable::draw(osg::RenderInfo & renderInfo={...})
> > > Line 868 + 0x13 bytes   C++
> > >         osgUtild.dll!osgUtil::RenderLeaf::render(osg::RenderInfo &
> > > renderInfo={...}, osgUtil::RenderLeaf * previous=0x09837b28)  Line 60
> > > + 0x19 bytes    C++
> > >         osgUtild.dll!osgUtil::RenderBin::drawImplementation(osg::RenderInfo
> > > & renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 408 + 0x19 bytes        C++
> > >         osgUtild.dll!osgUtil::RenderBin::draw(osg::RenderInfo &
> > > renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 373 + 0x17 bytes        C++
> > >         osgUtild.dll!osgUtil::RenderBin::drawImplementation(osg::RenderInfo
> > > & renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 458 + 0x35 bytes        C++
> > >         osgUtild.dll!osgUtil::RenderStage::drawImplementation(osg::RenderInfo
> > > & renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 1053    C++
> > >         osgUtild.dll!osgUtil::RenderBin::draw(osg::RenderInfo &
> > > renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 373 + 0x17 bytes        C++
> > >         osgUtild.dll!osgUtil::RenderStage::drawInner(osg::RenderInfo &
> > > renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28, bool &
> > > doCopyTexture=false)  Line 722  C++
> > >         osgUtild.dll!osgUtil::RenderStage::draw(osg::RenderInfo &
> > > renderInfo={...}, osgUtil::RenderLeaf * & previous=0x09837b28)  Line
> > > 913 + 0x1b bytes        C++
> > >         osgUtild.dll!osgUtil::SceneView::draw()  Line 1456 + 0x34 bytes C++
> > >         osgViewerd.dll!osgViewer::Renderer::draw()  Line 382 + 0xf bytes        C++
> > >         osgViewerd.dll!osgViewer::Renderer::operator()(osg::GraphicsContext
> > > * context=0x01926430)  Line 573 C++
> > >         osgd.dll!osg::GraphicsContext::runOperations()  Line 671 + 0x33 bytes   C++
> > >         osgd.dll!osg::RunOperations::operator()(osg::GraphicsContext *
> > > context=0x01926430)  Line 135   C++
> > >         osgd.dll!osg::GraphicsOperation::operator()(osg::Object *
> > > object=0x01926430)  Line 50 + 0x19 bytes        C++
> > >         osgd.dll!osg::OperationThread::run()  Line 413 + 0x26 bytes     C++
> > >         osgd.dll!osg::GraphicsThread::run()  Line 40    C++
> > >         OpenThreadsd.dll!OpenThreads::ThreadPrivateActions::StartThread(void
> > > * data=0x018f9740)  Line 106 + 0xf bytes        C++
> > >         msvcr80d.dll!__beginthreadex()  + 0x221 bytes
> > >         msvcr80d.dll!__beginthreadex()  + 0x1c7 bytes
> > >         kernel32.dll!@BaseThreadInitThunk at 12()  + 0xe bytes
> > >         ntdll.dll!__RtlUserThreadStart at 8()  + 0x23 bytes
> > >
> > >
> > >
> > >
> > >
> > >
> > > Here's the debug call stack of the original crash:
> > >
> > > osgTextd.dll!osg::ref_ptr<osg::StateSet>::get()  Line 71 + 0x11 bytes C++
> > > osgTextd.dll!osgText::Font::getStateSet()  Line 97 + 0x19 bytes C++
> > > > osgTextd.dll!osgText::Text::Text()  Line 61 + 0xc bytes C++
> > > osgtest.exe!UpdateTextOperation::load()  Line 556 + 0x2e bytes C++
> > > osgtest.exe!UpdateTextOperation::operator()(osg::Object *
> > > callingObject=0x00000000)  Line 499 C++
> > > osgd.dll!osg::OperationThread::run()  Line 413 + 0x26 bytes C++
> > > OpenThreadsd.dll!OpenThreads::ThreadPrivateActions::StartThread(void *
> > > data=0x0174cdb8)  Line 106 + 0xf bytes C++
> > > msvcr80d.dll!_callthreadstartex()  Line 348 + 0xf bytes C
> > > msvcr80d.dll!_threadstartex(void * ptd=0x0174da48)  Line 331 C
> > > kernel32.dll!7c80b683()
> > > [Frames below may be incorrect and/or missing, no symbols loaded for
> > > kernel32.dll]
> > >
> > >
> > > On 9/2/07, Robert Osfield <robert.osfield at gmail.com> wrote:
> > > > Hi Sherman,
> > > >
> > > > On 9/1/07, sherman wilcox <wilcox.sherman at gmail.com> wrote:
> > > > > If I run with --mt 1 it runs for a bit....however if I change that to --mt
> > > > > 10 it crashes immediately. Tried this on an old dual-proc and a new
> > > > > quad-core system. Here's the stack from the quad-core:
> > > > >
> > > > > > osgText.dll!osgText::Text::Text()  Line 61 + 0x5 bytes C++
> > > > >   osgtest.exe!UpdateTextOperation::load()  Line 556 + 0x24
> > > > > bytes C++
> > > > >   osgtest.exe!UpdateTextOperation::operator()(osg::Object *
> > > > > callingObject=0x00000000)  Line 498 + 0x5 bytes C++
> > > > >   osg.dll!osg::OperationThread::run()  Line 416 C++
> > > > >
> > > > > OpenThreads.dll!OpenThreads::ThreadPrivateActions::StartThread(void
> > > > > * data=0x00f7cda8)  Line 120 C++
> > > > >   msvcr80.dll!__endthreadex()  + 0x3b bytes
> > > > >   msvcr80.dll!__endthreadex ()  + 0xc7 bytes
> > > > >   kernel32.dll!@BaseThreadInitThunk at 12()  + 0xe bytes
> > > > >   ntdll.dll!__RtlUserThreadStart at 8 ()  + 0x23 bytes
> > > > >
> > > > > I'm grabbed a copy out of SVN about 30 minutes after you posted. So, I
> > > > > believe I have the right code. If you want me to perform any further
> > > > > testing/changes just yell.
> > > >
> > > > Originally I was getting crashes in the Text constructor to the lack
> > > > of thread safety on Node,Drawable and StateSet addParent.  This is now
> > > > mutexed so "shouldn't" be giving problems.. at least I don't get
> > > > problems with it any more.
> > > >
> > > > I'll test it once again to see if I can knock it over.  Perhaps its a
> > > > different problems to the addParent.  Could you try with a debug
> > > > version so we can get where abouts within the Text constructor its
> > > > crashing.
> > > >
> > > > Thanks,
> > > > Robert.
> > > > _______________________________________________
> > > > osg-users mailing list
> > > > osg-users at lists.openscenegraph.org
> > > > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> > > >
> > >
> > > _______________________________________________
> > > osg-users mailing list
> > > osg-users at lists.openscenegraph.org
> > > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> > >
> > >
> > >
> > _______________________________________________
> > osg-users mailing list
> > osg-users at lists.openscenegraph.org
> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>



More information about the osg-users mailing list