MantisBT - VTK
View Issue Details
0011208VTK(No Category)public2010-09-07 00:242010-09-08 12:36
David Gobbi 
David Gobbi 
highcrashalways
closedfixed 
 
 
0011208: Visual Studio 2003 crash for vtkOpenGLExtensionManager::ReadOpenGLExtensions()
The ReadOpenGLExtensions() method will call this->RenderWindow->Render() on Win32 machines if Render has not previously been called. This can cause a crash, because Render() in turn calls vtkOpenGLRenderWindow::OpenGLInit(), which calls vtkOpenGLRenderWindow::SetExtensionManager(0) and disassociates the ExtensionManager from the RenderWindow before creating a new ExtensionsManager.
This bug was tricky to find because it is hidden by VC80 and newer compilers. Here is a demonstration of how VC80 hides it. I added print statements to vtkOpenGLExtensionManager::ReadOpenGLExtensions() as follows:


  if (this->RenderWindow)
    {
    if (!this->RenderWindow->IsA("vtkOpenGLRenderWindow"))
      {
      // If the render window is not OpenGL, then it obviously has no
      // extensions.
      this->ExtensionsString = new char[1];
      this->ExtensionsString[0] = '\0';
      return;
      }
    cerr << "calling MakeCurrent " << this << "\n"; // ================
    this->RenderWindow->MakeCurrent();
    if (!this->RenderWindow->IsCurrent())
      {
      // Really should create a method in the render window to create
      // the graphics context instead of forcing a full render.
      cerr << "calling Render " << this << "\n"; // ================
      this->RenderWindow->Render();
      }
    cerr << "calling IsCurrent " << this << "\n"; // ================
    if (!this->RenderWindow->IsCurrent())
      {
      // this case happens with a headless Mac: a mac with a graphics card
      // with no monitor attached to it, connected to it with "Screen Sharing"
      // (VNC-like feature added in Mac OS 10.5)
      // see bug 8554.
      this->ExtensionsString = new char[1];
      this->ExtensionsString[0] = '\0';
      return;
      }
    }


This is the printout of a test crashing under VC71:


bin\ChartsCxxTests.exe TestMultipleScalarsToColors -D E:/Kitware/VTKData

Test timeout computed to be: 1500
calling MakeCurrent 04C84C88
calling Render 04C84C88
  setting ExtensionManager to 0
  created new extension manager 04C85ED0
  calling MakeCurrent 04C85ED0
  calling IsCurrent 04C85ED0
calling IsCurrent 04C84C88
*** Exception executing: Exit code 0xc0000354

The indentations show where the call to Render causes a new ExtensionManager to be created (I also added print statements to vtkOpenGLRenderWindow). The old ExtensionManager is destructed at the same time, which results in a crash when the call to Render() returns, since the original ExtensionManager has an invalid "this" pointer.

It is fairly obvious why the code would crash on VC71. So I had to wonder why it wasn't crashing on all Win32 compilers. To understand, look at the output when VTK is compiled with VC80:


bin\ChartsCxxTests.exe TestMultipleScalarsToColors -D E:/Kitware/VTKData

created new extension manager 03429150
calling MakeCurrent 03429150
calling Render 03429150
  setting ExtensionManager to 0
  created new extension manager 03429150
  calling MakeCurrent 03429150
  calling IsCurrent 03429150
calling IsCurrent 03429150
-- Process completed

The VC80 compiler first deletes the ExtensionManager, but then recreates it at exactly the same memory location. In other words, it is doing some memory-management tricks that hide the bug.

Update July 8, 2010:

Commit 0e84a23372139b50aab77deee9c6865efc2b4643 seems to fix this bug. It makes OpenGLInit call ExtensionManager->Modified() instead of deleting the extension manager. This will force the extension manager to re-read the extensions the next time its Update method is called.
No tags attached.
Issue History
2010-09-07 00:24David GobbiNew Issue
2010-09-07 10:43David GobbiNote Added: 0022107
2010-09-08 12:28David GobbiStatusbacklog => tabled
2010-09-08 12:28David GobbiAssigned To => David Gobbi
2010-09-08 12:30David GobbiNote Deleted: 0022107
2010-09-08 12:33David GobbiAdditional Information Updated
2010-09-08 12:36David GobbiStatustabled => closed
2010-09-08 12:36David GobbiResolutionopen => fixed
2011-06-16 13:11Zack GalbreathCategory => (No Category)

There are no notes attached to this issue.