MantisBT - VTK
View Issue Details
0001728VTK(No Category)public2005-04-01 17:082013-04-05 20:21
System Admin 
David Cole 
urgentmajoralways
closedfixed 
 
 
0001728: destroying vtkTkRenderWidget crashes on X
The following tcl code crashes on X

vtkTkRenderWidget .t
pack .t
destroy .t
No tags attached.
Issue History
2008-11-30 09:27Mathieu MalaterreAssigned ToMathieu Malaterre => David Cole
2011-01-19 10:20David ColeNote Added: 0024911
2011-01-19 10:20David ColeStatustabled => @80@
2011-01-19 10:20David ColeResolutionopen => fixed
2011-06-16 13:11Zack GalbreathCategory => (No Category)
2013-04-05 20:21Berk GeveciStatuscustomer review => closed

Notes
(0003820)
Steve Pieper   
2006-03-01 18:56   
Steve and Sebastien both confirmed that this problem occurs when tcl is compiled with --enable-threads but not otherwise.
(0003829)
Mathieu Malaterre   
2006-03-03 11:46   
The code make use of ckfree to free a strdup. If one change the code to free, it works fine on linux/UNIX, but not on some Win32 (works with active state).
I believe this is because ckfree use mutex lock in the threaded tcl lib, and not in the non threaded one, whereas the mutex lock should be done at VTK level.
(0004065)
Sebastien Barre   
2006-05-05 11:44   
Alright, I think I nailed this one.

The whole problem had nothing to do with ActiveStateTcl being built with thread enabled, but was related to cross-DLL boundaries and the fact that ActiveState is using a non-debug CRT (msvcrt.dll) DLL, whereas our debug build of VTK (or KWWidgets) would use a debug CRT (msvcp71d.dll). This can be done, but you have to be extra-careful if you are allocating an object from within one DLL, and de-allocating it from the other: when that happens, the infamous assertion fails: Expression: _CrtIsValidHeapPointer(pUserData).

Changing ckfree() to free() to match strdup() was wrong. The opposite had to be done, strdup() had to be changed into a ckalloc() + strcpy().

ckfree() and ckalloc() are Tcl wrappers around free()/malloc(), and provide extra debugging. They have to match so that the corresponding call to free()/malloc() are performed from the same DLL.
Two scenarios were involved:
1) in most (if not all) of our apps, we create a vtkTkRenderWidget by specifying the renderwindow explicitly, that way: vtkTkRenderWidget .t -rw renWin
At this point, the -rw parameter is handled by *Tcl*, which performs a ckalloc() for us from its own CRT DLL (msvcrt.dll). Therefore this pointer *has* to be released with ckfree() so that it is released from the same DLL. This is what was done for a long time, before the recent change to free().
2) In the example that was submitted for the crash, no renderwindow is provided, so vtkTkRenderWidget is creating for us. The Tcl name of the vtkRenderWindow was copied into a datastructure (self->RW) using strdup(), which was therefore performed from *our* debug DLL (msvcp71.dll), *not* from Tcl's CRT DLL (msvcrt.dll). That very name was later on released with ckfree(), from Tcl's CRT DLL, thus crossing the DLL-boundaries and raising the assertion. The name should have been allocated with ckalloc() for everything to happen in the same DLL (msvcrt.dll).

Now all those scenarios were working more or less fine so far because very few people let vtkTkRenderWidget create the renderwindow automatically. Also, in ParaView and such, we use Tcl static libs.

Hopefully this is good now.
As far as KWWidgets is concerned, the dashboard still has some issues because ActiveState Tcl provide its own version of Gettext, the internationalization lib. I'm looking at that, but Slicer3 should not be affected since it does not turn the internationalization framework ON.
(0024911)
David Cole   
2011-01-19 10:20   
Marking as resolved based on Sebastien's latest note.