diff -u -r OpenSceneGraph-3.0.1-orig/src/osgUtil/CullVisitor.cpp OpenSceneGraph-3.0.1/src/osgUtil/CullVisitor.cpp
--- OpenSceneGraph-3.0.1-orig/src/osgUtil/CullVisitor.cpp	2011-05-09 13:51:52.000000000 +0200
+++ OpenSceneGraph-3.0.1/src/osgUtil/CullVisitor.cpp	2012-04-02 01:04:12.815823700 +0200
@@ -1264,7 +1281,7 @@
 namespace osgUtil
 {
 
-class RenderStageCache : public osg::Object
+class RenderStageCache : public osg::Object, public osg::Observer
 {
     public:
     
@@ -1273,9 +1290,19 @@
         
         META_Object(osgUtil, RenderStageCache);
         
+        virtual ~RenderStageCache()
+        {
+            for(std::map<osg::Referenced*, osg::ref_ptr<RenderStage> >::iterator itr = _renderStageMap.begin();
+                itr != _renderStageMap.end(); ++itr)
+            {
+                itr->first->removeObserver(this);
+            }
+        }
+
         void setRenderStage(CullVisitor* cv, RenderStage* rs)
         {
             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
+            cv->addObserver(this);
             _renderStageMap[cv] = rs;
         }        
 
@@ -1285,7 +1312,15 @@
             return _renderStageMap[cv].get();
         }
         
-        typedef std::map<CullVisitor*, osg::ref_ptr<RenderStage> > RenderStageMap;
+        virtual void objectDeleted(void* obj)
+        {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
+            _renderStageMap.erase(static_cast<osg::Referenced*>(obj));
+        }
+        
+        // can't store a osgUtil::CullVisitor* here because by the time it's destroyed we can 
+        // no longer downcast it due to virtual inheritance being used.
+        typedef std::map<osg::Referenced*, osg::ref_ptr<RenderStage> > RenderStageMap;
         
         /** Resize any per context GLObject buffers to specified size. */
         virtual void resizeGLObjectBuffers(unsigned int maxSize)
