Hi Ulrich,
The stack trace suggests that the DatabasePager has loaded a subgraph
and is now compiling a list of all the OpenGL objects for it, and the
associated traversal of this still valid scene graph (because the
DatabasePager still owns it) is touching upon the osgTerrain::Terrain
pointer to the Terrain object that should be the eventual owner of
this new sub graph, but... you've deleted it.
What it looks like to be is that NodePath that osgTerrain::TerrainTile
is accessing has been invalidated by your main thread that is doing
the deleting. The DatabasePager does a little trick of artificially
seed the compile traversal that it does with the parent NodePath of
the node that it'll be adding the new subgraph to, the code looks
like:
osg::NodePath nodePath;
osg::NodePathList nodePathList =
groupForAddingLoadedSubgraph->getParentalNodePaths();
if (!nodePathList.empty()) nodePath = nodePathList.front();
nodePath.push_back(groupForAddingLoadedSubgraph.get());
Now NodePath doesn't take any references, it's just a
std::vector<osg::Node*>. To fix this problem we'd need to use a
RefNodePath, and for the getParentNodePaths() to populate a list of
RefNodePath rather than a list of NodePath.
The other solution would be to wait till the DatabasePager is idle
before your do a delete of the scene graph.
Robert.
On Tue, Jun 2, 2009 at 12:02 PM, Ulrich Hertlein <[email protected]> wrote:
> Hi Robert,
>
> On 2/6/09 12:49 PM, Robert Osfield wrote:
>>
>> Nothing special should be required when removing a PageLOD database
>> from the scene graph. One should just need to take the usual care
>> about threading.
>
> Okay thanks.
>
>> The fact that you are getting a crash in osgTerrain
>> does suggest that the DatabasePager thread is trying to do something
>> on a scene graph that it doesn't have a reference to, but what code
>> this might be I just can't say without at least a stack trace.
>
> I managed to get one :-)
>
> Program received signal EXC_BAD_ACCESS, Could not access memory.
> Reason: KERN_INVALID_ADDRESS at address: 0xc0000000
> [Switching to process 14997 thread 0xc903]
> 0x945f4a03 in __dynamic_cast ()
> (gdb) where
> #0 0x945f4a03 in __dynamic_cast ()
> #1 0x1c169f73 in osgTerrain::TerrainTile::traverse ()
> #2 0x0347fea3 in osg::NodeVisitor::traverse ()
> #3 0x03493aa6 in
> osgDB::DatabasePager::FindCompileableGLObjectsVisitor::apply ()
> #4 0x036c495b in osg::NodeVisitor::apply ()
> #5 0x1c16e15f in osgTerrain::TerrainTile::accept ()
> #6 0x036a8f94 in osg::NodeAcceptOp::operator() ()
> #7 0x036a960d in
> std::for_each<__gnu_cxx::__normal_iterator<osg::ref_ptr<osg::Node>*,
> std::vector<osg::ref_ptr<osg::Node>, std::allocator<osg::ref_ptr<osg::Node>
>> > >, osg::NodeAcceptOp> ()
> #8 0x036d292c in osg::PagedLOD::traverse ()
> #9 0x0347fea3 in osg::NodeVisitor::traverse ()
> #10 0x03493aa6 in
> osgDB::DatabasePager::FindCompileableGLObjectsVisitor::apply ()
> #11 0x036c495b in osg::NodeVisitor::apply ()
> #12 0x036c4b37 in osg::NodeVisitor::apply ()
> #13 0x036c4b59 in osg::NodeVisitor::apply ()
> #14 0x036d46cd in osg::PagedLOD::accept ()
> #15 0x03675a7f in osg::Group::traverse ()
> #16 0x0347fea3 in osg::NodeVisitor::traverse ()
> #17 0x03493aa6 in
> osgDB::DatabasePager::FindCompileableGLObjectsVisitor::apply ()
> #18 0x036c495b in osg::NodeVisitor::apply ()
> #19 0x03677845 in osg::Group::accept ()
> #20 0x03478f8b in osgDB::DatabasePager::DatabaseThread::run ()
> #21 0x02c2af1c in OpenThreads::ThreadPrivateActions::StartThread ()
> #22 0x97037155 in _pthread_start ()
> #23 0x97037012 in thread_start ()
>
>>> are there any special steps involved to unload a PagedLOD database?
>>> What I want to do is release the main memory and OpenGL resources
>>> associated
>>> with a PagedLOD.
>>>
>>> My setup is roughtly the following:
>>> - osgViewer::Viewer in single-threaded mode
>>> - rendering is triggered on-demand by calling 'viewer->frame()'
>>> - osg::Group* sceneNode and osg::Node* modelNode (both as osg::ref_ptr)
>>> - to release the model I call sceneNode->removeChild(modelNode) and then
>>> set
>>> modelNode = 0 to invalidate the ref_ptr
>>> - after that the frame draw is not triggered anymore.
>>>
>>> This works *most* of the times but I sporadicly get a crash in
>>> osgTerrain::traverse which appears like there is some thread still
>>> running
>>> on the database.
>
> _______________________________________________
> 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