Hi,

I have just received a crash in the example osgtexture2d.

This sounds like the problem you are talking about, as it doesn't happen
100% of the time sort of 1-4/10 times everytime its lanched or sometimes
within a few seconds of opening, other times a few minutes..

Here is a stack trace which does lead back to osgtext.

 

void Text::drawTextWithBackdrop(osg::State& state, const osg::Vec4&
colorMultiplier) const

{

    unsigned int contextID = state.getContextID();

 

    for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin();

        titr!=_textureGlyphQuadMap.end();

        ++titr)

    {

 

It crashes incrementing the pointer at this point above:

Variables:

-           titr  ({_ptr=0x3ebbd70831e853be },{_glyphs=[564211582](...,...)
_coords=[-26984783](...) _transformedCoords={...} ...})
std::_Tree<std::_Tmap_traits<osg::ref_ptr<osgText::GlyphTexture>,osgText::Te
xt::GlyphQuads,std::less<osg::ref_ptr<osgText::GlyphTexture>
>,std::allocator<std::pair<osg::ref_ptr<osgText::GlyphTexture> const
,osgText::Text::GlyphQuads> >,0> >::iterator

-           ptr   ({_ptr=0x3ebbd70831e853be },{_glyphs=[564211582](...,...)
_coords=[-26984783](...) _transformedCoords={...} ...})
std::pair<osg::ref_ptr<osgText::GlyphTexture> const
,osgText::Text::GlyphQuads>

-           first {_ptr=0x3ebbd70831e853be }    const
osg::ref_ptr<osgText::GlyphTexture>

-           _ptr  0x3ebbd70831e853be {_margin=??? _marginRatio=???
_usedY=??? ...}      osgText::GlyphTexture *

+           osg::Texture2D    {_image={...} _textureWidth=???
_textureHeight=??? ...}      osg::Texture2D

            _margin     CXX0030: Error: expression cannot be evaluated  

            _marginRatio      CXX0030: Error: expression cannot be evaluated


            _usedY      CXX0030: Error: expression cannot be evaluated  

            _partUsedX  CXX0030: Error: expression cannot be evaluated  

            _partUsedY  CXX0030: Error: expression cannot be evaluated  

            _glyphs     [...]()
std::vector<osg::ref_ptr<osgText::Glyph>,std::allocator<osg::ref_ptr<osgText
::Glyph> > >

+           _glyphsToSubload  {_array=[...]() }
osg::buffered_object<std::vector<osgText::Glyph const
*,std::allocator<osgText::Glyph const *> > >

+           _mutex      {_prvData=??? _mutexType=??? }
OpenThreads::Mutex

-           second      {_glyphs=[564211582](...,...)
_coords=[-26984783](...) _transformedCoords={...} ...}
osgText::Text::GlyphQuads

+           _glyphs     [564211582](...,...)    std::vector<osgText::Glyph
*,std::allocator<osgText::Glyph *> >

+           _coords     [-26984783](...)
std::vector<osg::Vec2f,std::allocator<osg::Vec2f> >

+           _transformedCoords      {_array=[-90833](...) }
osg::buffered_object<std::vector<osg::Vec3f,std::allocator<osg::Vec3f> > >

+           _texcoords  [1638783872]({_v=0x3ed7ae123196a920
},{_v=0x3ed7ae123196a928 },{_v=0x3ed7ae123196a930 },{_v=0x3ed7ae123196a938
},{_v=0x3ed7ae123196a940 },{_v=0x3ed7ae123196a948 },{_v=0x3ed7ae123196a950
},{_v=0x3ed7ae123196a958 },{_v=0x3ed7ae123196a960 },{_v=0x3ed7ae123196a968
},{_v=0x3ed7ae123196a970 },{_v=0x3ed7ae123196a978 },{_v=0x3ed7ae123196a980
},{_v=0x3ed7ae123196a988 },{_v=0x3ed7ae123196a990 },{_v=0x3ed7a ,...)
std::vector<osg::Vec2f,std::allocator<osg::Vec2f> >

+           _lineNumbers      [2091425331](...,...)   std::vector<unsigned
int,std::allocator<unsigned int> >

+           _transformedBackdropCoords    0x000000000289dc48
{_array=[1181049552]([...](),[...](),[...](),[...](),[...](),[...](),[...]()
,[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[..
.](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...]()
,[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[..
.](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](),[...](
osg::buffered_object<std::vector<osg::Vec3f,std::allocator<osg::Vec3f> > >
[8]

+           _colorCoords      [-954718799](...)
std::vector<osg::Vec4f,std::allocator<osg::Vec4f> >

+           this  0x00000000028679e0 {_textureGlyphQuadMap=[1](...,...)
_enableDepthWrites=true _backdropType=NONE ...} const osgText::Text * const

+           state
{_quadIndicesGLushort=[654](0,1,3,1,2,3,4,5,7,5,6,7,8,9,11,9,10,11,12,13,15,
13,14,15,16,17,19,17,18,19,20,21,23,21,22,23,24,25,27,25,26,27,28,29,31,29,3
0,31,32,33,35,33,34,35,36,37,39,37,38,39,40,41,43,41,42,43,44,45,47,45,46,47
,48,49,51,49,50,51,52,53,55,53,54,55,56,57,59,57,58,59,60,61,63,61,62,63,64,
65,67,65,66,67,68,69,71,69,70,71,72,73,75,73,74,75,76,77,79,77,78,79,80,81,8
3,81,82,83,84,85,.       osg::State &

+           colorMultiplier   {_v=0x0000000007b3e6c0 }      const osg::Vec4f
&

            contextID   0     unsigned int

 

Stack:

                msvcp90d.dll!std::_Debug_message(const wchar_t *
message=0x000007feeb2b8650, const wchar_t * file=0x000007feeb2b6660,
unsigned int line=384)  Line 24             C++

 
osg92-osgTextd.dll!std::_Tree<std::_Tmap_traits<osg::ref_ptr<osgText::GlyphT
exture>,osgText::Text::GlyphQuads,std::less<osg::ref_ptr<osgText::GlyphTextu
re> >,std::allocator<std::pair<osg::ref_ptr<osgText::GlyphTexture> const
,osgText::Text::GlyphQuads> >,0> >::const_iterator::_Inc()  Line 385
C++

 
osg92-osgTextd.dll!std::_Tree<std::_Tmap_traits<osg::ref_ptr<osgText::GlyphT
exture>,osgText::Text::GlyphQuads,std::less<osg::ref_ptr<osgText::GlyphTextu
re> >,std::allocator<std::pair<osg::ref_ptr<osgText::GlyphTexture> const
,osgText::Text::GlyphQuads> >,0> >::const_iterator::operator++()  Line 275
C++

>
osg92-osgTextd.dll!std::_Tree<std::_Tmap_traits<osg::ref_ptr<osgText::GlyphT
exture>,osgText::Text::GlyphQuads,std::less<osg::ref_ptr<osgText::GlyphTextu
re> >,std::allocator<std::pair<osg::ref_ptr<osgText::GlyphTexture> const
,osgText::Text::GlyphQuads> >,0> >::iterator::operator++()  Line 476
C++

 
osg92-osgTextd.dll!osgText::Text::drawTextWithBackdrop(osg::State &
state={...}, const osg::Vec4f & colorMultiplier={...})  Line 1628 + 0xa
bytes          C++

 
osg92-osgTextd.dll!osgText::Text::renderWithDelayedDepthWrites(osg::State &
state={...}, const osg::Vec4f & colorMultiplier={...})  Line 1608  C++

 
osg92-osgTextd.dll!osgText::Text::drawImplementation(osg::State &
state={...}, const osg::Vec4f & colorMultiplier={...})  Line 1390  C++

 
osg92-osgTextd.dll!osgText::Text::drawImplementation(osg::RenderInfo &
renderInfo={...})  Line 1207                C++

               osg92-osgd.dll!osg::Drawable::draw(osg::RenderInfo &
renderInfo={...})  Line 915           C++

 
osg92-osgUtild.dll!osgUtil::RenderLeaf::render(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * previous=0x0000000002967250)  Line
65                C++

 
osg92-osgUtild.dll!osgUtil::RenderBin::drawImplementation(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)  Line
460            C++

               osg92-osgUtild.dll!osgUtil::RenderBin::draw(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)  Line
425              C++

 
osg92-osgUtild.dll!osgUtil::RenderBin::drawImplementation(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)  Line
510            C++

 
osg92-osgUtild.dll!osgUtil::RenderStage::drawImplementation(osg::RenderInfo
& renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)
Line 1398          C++

               osg92-osgUtild.dll!osgUtil::RenderBin::draw(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)  Line
425              C++

 
osg92-osgUtild.dll!osgUtil::RenderStage::drawInner(osg::RenderInfo &
renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250, bool
& doCopyTexture=false)  Line 933 C++

               osg92-osgUtild.dll!osgUtil::RenderStage::draw(osg::RenderInfo
& renderInfo={...}, osgUtil::RenderLeaf * & previous=0x0000000002967250)
Line 1239           C++

               osg92-osgUtild.dll!osgUtil::SceneView::draw()  Line 1447
C++

               osg92-osgViewerd.dll!osgViewer::Renderer::draw()  Line 725 +
0x13 bytes          C++

 
osg92-osgViewerd.dll!osgViewer::Renderer::operator()(osg::GraphicsContext *
context=0x0000000002933d60)  Line 894                C++

               osg92-osgd.dll!osg::GraphicsContext::runOperations()  Line
778                C++

 
osg92-osgd.dll!osg::RunOperations::operator()(osg::GraphicsContext *
context=0x0000000002933d60)  Line 138                C++

               osg92-osgd.dll!osg::GraphicsOperation::operator()(osg::Object
* object=0x0000000002933d60)  Line 54                C++

               osg92-osgd.dll!osg::OperationThread::run()  Line 429     C++

               osg92-osgd.dll!osg::GraphicsThread::run()  Line 41
C++

 
ot12-OpenThreadsd.dll!OpenThreads::ThreadPrivateActions::StartThread(void *
data=0x0000000002890008)  Line 113 + 0x10 bytes               C++

 

 

Sorry for the long post!

And let me know if I can be of further assistance

 

 

Regards

Martin

 

From: [email protected]
[mailto:[email protected]] On Behalf Of mikael
lemercier
Sent: 06 April 2012 09:43
To: OpenSceneGraph Users
Subject: Re: [osg-users] osg::Referenced::unref() thread safety

 

For information, my problem ( "Warning: deleting still referenced object XXX
of type 'XXX' the final reference count was 1, memory corruption possible."
Followed by a crash. ) came from osg plugins in 2.9.5 version.

In Texture1D.cpp, Texture2D.cpp, etc..., the XXX_readLocalData function
(that can be called in a thread) stores an Image C pointer. Meanwhile this
Image can be released from the cache in the main thread by
removeExpiredObjectsInCache().



2012/2/8 mikael lemercier <[email protected]>

Thanks for your answer Robert,

My test app was clearly a misuse of ref_ptr.
So, I retested it with observer_ptr instead of C pointer.

With the head revision, I haven't been able to reproduce the warning thanks
to this test in the ObserverSet::addRefLock() function :

    if (refCount == 1)
    {
        // The object is in the process of being deleted, but our
        // objectDeleted() method hasn't been run yet (and we're
        // blocking it -- and the final destruction -- with our lock).
        _observedObject->unref_nodelete();
        return 0;
    }
When assigning an observer_ptr to a ref_ptr in my second thread, the
simultaneous destruction of the pointed object is well checked and then the
refCount is not incremented.
The ref_ptr is set to NULL. All works fine.

With the 2.9.5 version, there was no ref_ptr constructor taking an
observer_ptr argument.
So we have to be careful also when using observer_ptr. It could lead to
misuse of ref_ptr too, since we need to use the observed C pointer to assign
it to ref_ptr.
Indeed, the warning is reproduced with the following assignment in my test:
_imageRefPtr = _imageObserverPtr.get();

Thanks again








2012/2/7 Robert Osfield <[email protected]>

HI Mikael,

Thanks for the details.

Your comment about the delete not being mutexed made me think about
why the ref count could get to zero and then have the thread progress
to delete, and one shouldn't progress to delete as long as the ref
count is non zero.  This led me to wonder just how with your code this
could happen and I think the crux of it is that in your test app you
are creating an object using a C pointer to it, then letting different
threads assign and reset ref_ptr<> independently.

For the case where it crashes my guess is that the main thread creates
the MyThread and this stores a C pointer to the Image, then the main
thread calls startThread() which returns to main which then assigns
and resets the ref_ptr<>, if this assign/reset happens before the
MyThread::run() gets going and creates it's own ref to the Image then
it'll be deleted before it gets a chance to increment the ref count.
This isn't a bug in ref counting, it's a bug in your code - MyThread
should never have been written with a C pointer in the first place, as
this opens the door to the sequence I've explain and problem you are
seeing.

So I think this example is good one for demonstrating how dangerous it
is to use C pointers and ref_ptr<>'s without taking proper care about
sequencing of the creation and assignments.  These types of errors are
very hard to spot, even on an example as small of yours it's not
obvious, so taking a full scale app it becomes very hard to spot these
problems indeed.  The best defence is to be very careful anytime you
pass C pointers around, and especially carefully when you retain C
pointers for use later.

Robert.



On 7 February 2012 13:50, mikael lemercier <[email protected]> wrote:
>
> 2012/2/7 Robert Osfield <[email protected]>
>>
>> Also what hardware, OS, dev environment are you working on?
>
>
> I'm working on:
> - Hardware : Intel Core i7-2600
> - OS : Windows 7
> - Dev environment : Visual 2010
> - Build config : x64
>
> I also reproduced the problem on:
> - Hardware : Intel Core i7-2600
> - OS : OpenSuse 11.1
> - Dev environment : Eclipse
>
>
>>
>> Could you also check whether the OSG is using atomic ref counting or
>> OpenThreads::Mutex version? include/OpenThreads/Config will reveal
>> which should be being used.
>
>
> It's using atomic ref counting in my case :
> _OSG_REFERENCED_USE_ATOMIC_OPERATIONS is defined.
> But the problem might also exist with Mutex, since in both cases the
delete
> part is not locked.
>
>>
>> Could you also outline how you are running your tests.
>
>
> To reproduce the problem, without any interference from my work, I
inserted
> my test file directly in the osg solution.
> I just replaced osgviewer.cpp by my test file (joined with my first
> message).
> As I said before, I also added a sleep() of 1s to the Referenced::unref()
> function so that the created thread has time to increment the refCount
> before the main thread calls the delete.
>
>
>
>
>
>
>

> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

 

 

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to