From: SourceForge.net <no...@so...> - 2005-09-29 17:50:25
|
Bugs item #749908, was opened at 2003-06-05 21:19 Message generated for change (Comment added) made by dgp You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=112997&aid=749908&group_id=12997 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 74. Application Embedding Group: current: 8.4.11 Status: Open Resolution: None Priority: 9 Submitted By: Joe Mistachkin (mistachkin) Assigned to: Donal K. Fellows (dkf) Summary: problems with threaded Tk and multiple interps Initial Comment: The platform in question is Windows NT/2000. If I start up tetris.tcl, then close it, then try to run it again in the same interp, I get the usual (expected) error message "can't invoke wm command, app has been destroyed". However, if I then delete the interpreter, create a new one, and attempt to run tetris.tcl, I get: bad screen distance "aaaaaaaaaaaaaaaaaaaaïÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍï0ïD" (default value for "HOME" in widget ".r.board") invoked from within "canvas $widget(board) -width $tetris(width) - height $tetris(height) -bg gray" (procedure "Init" line 85) invoked from within "Init" (in namespace eval "::Tetris" script line 1319) invoked from within "namespace eval Tetris {; variable tetris variable block variable players variable stats variable pmap variable piece variable widget ## VERSION: set..." (file "tetris.tcl" line 25) invoked from within "source "tetris.tcl"" Some digging reveals the offending code may be in tkOldConfig.c. Similar garbage is displayed if you try to re-run the Gem Game. In addition, a panic caused by TlsFree failing results if you attempt to exit the process after creating an interpreter with Tk, delete it, and create another one. This is definately a recent issue as I know I've done this sort of thing with 8.3.x and [i believe] 8.4.x. I cannot imagine how this behavior could be by design. ---------------------------------------------------------------------- >Comment By: Don Porter (dgp) Date: 2005-09-29 13:50 Message: Logged In: YES user_id=80530 I'd prefer to find the places in Tk where exit handlers are being set after exit handlers have run and fix those. If we really, really are incapable of doing that, then we should stop dancing around this and create a public Tcl_InExit() because every extension will have the same problem of needing to guard its calls to Tcl_CreateExitHandler(). ---------------------------------------------------------------------- Comment By: Daniel A. Steffen (das) Date: 2005-09-29 13:10 Message: Logged In: YES user_id=90580 TclInExit() is already in the tcl internal stubs table... The only change required to fix the OSX build is to add #include <tclInt.h> to tkEvent.c in fact, as discussed, it is really tkUnixPort.h and tkWinPort.h that are incorrect in that they include tclInt.h. If these were removed, the #include <tclInt.h> in tkEvent.c would also be necessary for those platforms. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-09-29 12:49 Message: Logged In: YES user_id=113501 It will bring the bug back. When I initially tested my fixes, I discovered that we cannot create the exit handlers if we are already exiting. Please restore the call and find another way to fix the compile issues on Mac OS X (perhaps add TclInExit to the internal stubs table?). ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2005-09-29 09:41 Message: Logged In: YES user_id=80530 The HEAD has been revised to disable the TclInExit() calls. Please check whether that change has brought this bug back. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-09-29 08:59 Message: Logged In: YES user_id=79902 I'm happy to make changes if I understand what changes people want made. Does this mean that tkEvent.c should #include <tclInt.h>? ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2005-09-26 15:22 Message: Logged In: YES user_id=80530 Agreed. A big part of "Header reform" (Tcl Feature Request 922727) was re-establishing the ordering tcl.h < tclPort.h < tclInt.h Don't do anything to undo that. Beyond that, do whatever we can to drop any Tk need for tclInt.h. ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2005-09-26 14:51 Message: Logged In: YES user_id=72656 Indeed, the internal headers should *not* be required from the Port.h header files. The *Port.h should be include-able by regular extensions without requiring the internal headers. ---------------------------------------------------------------------- Comment By: Daniel A. Steffen (das) Date: 2005-09-26 12:29 Message: Logged In: YES user_id=90580 the problem was that on macosx, tclInt.h is not #included in tkMacOSXPort.h (and I'm not convinced it['s a good idea to add it add it there globally just for the sake of using this one tcl internal API in tkEvent.c...) the convention in the tk/macosx sources is to include internal tcl headers only in the source files that explicitly need them, i.e. I would prefer that #include <tclInt.h> be added at the top of tkEvent.c if the TclInExit() internal tcl API can't be avoided. With that change, HEAD builds fine on aqua once again. ---------------------------------------------------------------------- Comment By: Daniel A. Steffen (das) Date: 2005-09-26 12:07 Message: Logged In: YES user_id=90580 this change breaks the current tk HEAD build, looks like the patch was not applied fully? generic/tkEvent.c: In function `TkCreateExitHandler': generic/tkEvent.c:1883: warning: implicit declaration of function `TclInExit' ld: Undefined symbols: _TclInExit ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-09-21 11:17 Message: Logged In: YES user_id=79902 Hmm, patch can't even be applied *by hand* to 8.4, so we're done. Reopen if the Tcl_FindHashEntry problem still persists in 8.5 (it shouldn't...) ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-09-21 08:13 Message: Logged In: YES user_id=79902 Applied the exit-handler changes to the HEAD; backport still pending. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-09-15 11:34 Message: Logged In: YES user_id=79902 It's not crashing or a security fault, so it's not a prio9 bug. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-09-15 05:02 Message: Logged In: YES user_id=113501 Any update on the regressions we are seeing in the test suite? ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-08-22 01:47 Message: Logged In: YES user_id=113501 This fix appears to possibly be causing regressions in the Tk test suite on Windows (for example, image.test): Test files sourced into current interpreter Running tests that match: * Skipping test files that match: l.*.test Only running test files that match: *.test Tests began at Sun Aug 21 22:30:25 -0700 2005 bell.test Bell should ring now ... bgerror.test bind.test bitmap.test border.test button.test canvImg.test canvPs.test canvRect.test canvText.test canvWind.test canvas.test choosedir.test clipboard.test clrpick.test cmds.test color.test config.test cursor.test dialog.test embed.test entry.test event.test filebox.test focus.test focusTcl.test font.test frame.test geometry.test get.test grab.test grid.test id.test image.test ==== image-1.10 Tk_ImageCmd procedure, "create" option with same name as main window FAILED ==== Contents of test case: set code [loadTkCommand] append code { update puts [list [catch {image create photo .} msg] $msg] exit } set script [makeFile $code script] set x [list [catch {exec [interpreter] <$script} msg] $msg] removeFile script set x ---- Result was: 1 {1 {images may not be named the same as the main window} called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {1 {images may not be named the same as the main window}} ==== image-1.10 FAILED ==== image-1.11 Tk_ImageCmd procedure, "create" option with same name as main window after renaming FAILED ==== Contents of test case: set code [loadTkCommand] append code { update puts [list [catch {rename . foo;image create photo foo} msg] $msg] exit } set script [makeFile $code script] set x [list [catch {exec [interpreter] <$script} msg] $msg] removeFile script set x ---- Result was: 1 {1 {images may not be named the same as the main window} called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {1 {images may not be named the same as the main window}} ==== image-1.11 FAILED imgBmap.test imgPPM.test imgPhoto.test listbox.test main.test menu.test menuDraw.test menubut.test message.test msgbox.test obj.test oldpack.test option.test pack.test panedwindow.test place.test raise.test safe.test ==== safe-1.2 Safe Tk loading into an interpreter FAILED ==== Contents of test case: catch {safe::interpDelete a} safe::interpCreate a safe::loadTk a set l [lsort [interp hidden a]] safe::interpDelete a set l ---- Result was: bell cd clipboard encoding exec exit fconfigure file glob grab load menu open pwd selection socket source tk_chooseColor tk_chooseDirectory tk_getOpenFile tk_getSaveFile tk_messageBox toplevel wm ---- Result should have been (exact matching): bell cd clipboard encoding exec exit fconfigure file glob grab load menu open pwd selection send socket source tk_chooseColor tk_chooseDirectory tk_getOpenFile tk_getSaveFile tk_messageBox toplevel wm ==== safe-1.2 FAILED scale.test scrollbar.test select.test send.test spinbox.test text.test ==== text-8.18 TextWidgetCmd procedure, "replace" option FAILED ==== Contents of test case: list [catch {.t replace 3.1 2.3 foo} err] $err ---- Result was: 1 {Index "2.3" before "3.1" in the text} ---- Result should have been (exact matching): 1 {Index "2.3" before "3.1" in the text.} ==== text-8.18 FAILED textBTree.test textDisp.test textImage.test textIndex.test textMark.test textTag.test textWind.test ==== textWind-10.4 EmbWinLayoutProc procedure, error in creating window FAILED ==== Contents of test case: .t delete 1.0 end .t insert 1.0 "Some sample text" catch {destroy .t.f} .t window create 1.5 -create { frame .t.f frame .t.f.f -width 10 -height 20 -bg $color } set msg {} set count 0 while {([llength $msg] < 2) && ($count < 100)} { update ; incr count; .t bbox 1.5 ; after 10 } lappend msg [.t bbox 1.5] [winfo exists .t.f.f] ---- Result was: {{can't embed .t.f.f relative to .t}} {40 12 0 0} 1 ---- Result should have been (exact matching): {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} {40 12 0 0} 1 ==== textWind-10.4 FAILED ==== textWind-10.6 EmbWinLayoutProc procedure, error in creating window FAILED ==== Contents of test case: .t delete 1.0 end .t insert 1.0 "Some sample text" catch {destroy .t2} .t window create 1.5 -create { toplevel .t2 -width 100 -height 150 wm geom .t2 +0+0 concat .t2 } set msg {} update lappend msg [.t bbox 1.5] ---- Result was: {{can't embed .t2 relative to .t}} {40 12 0 0} ---- Result should have been (exact matching): {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} {40 12 0 0} ==== textWind-10.6 FAILED tk.test unixButton.test unixEmbed.test unixFont.test unixMenu.test unixSelect.test unixWm.test util.test visual.test visual_bb.test winButton.test winClipboard.test winDialog.test winFont.test winMenu.test winSend.test winWm.test ==== winWm-5.1 UpdateGeometryInfo: menu resizing FAILED ==== Contents of test case: set result {} toplevel .t frame .t.f -width 150 -height 50 -bg red pack .t.f update set result [winfo height .t] menu .t.m .t.m add command -label foo .t conf -menu .t.m update lappend result [winfo height .t] .t.m add command -label "thisisreallylong" .t.m add command -label "thisisreallylong" update lappend result [winfo height .t] destroy .t set result ---- Result was: 50 50 32 ---- Result should have been (exact matching): 50 50 50 ==== winWm-5.1 FAILED window.test ==== window-2.5 Tk_DestroyWindow, cleanup half dead windows at exit FAILED ==== Contents of test case: set code [loadTkCommand] append code { toplevel .t update bind .t <Destroy> exit destroy .t } set script [makeFile $code script] if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} { set error 1 } else { set error 0 } removeFile script list $error $msg ---- Result was: 1 {called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {} ==== window-2.5 FAILED ==== window-2.6 Tk_DestroyWindow, cleanup half dead windows at exit FAILED ==== Contents of test case: set code [loadTkCommand] append code { toplevel .t update bind .t <Destroy> exit destroy . } set script [makeFile $code script] if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} { set error 1 } else { set error 0 } removeFile script list $error $msg ---- Result was: 1 {called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {} ==== window-2.6 FAILED ==== window-2.7 Tk_DestroyWindow, cleanup half dead windows at exit FAILED ==== Contents of test case: set code [loadTkCommand] append code { toplevel .t toplevel .t.f update bind .t.f <Destroy> exit destroy . } set script [makeFile $code script] if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} { set error 1 } else { set error 0 } removeFile script list $error $msg ---- Result was: 1 {called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {} ==== window-2.7 FAILED ==== window-2.8 Tk_DestroyWindow, cleanup half dead windows at exit FAILED ==== Contents of test case: set code [loadTkCommand] append code { toplevel .t1 toplevel .t2 toplevel .t3 update bind .t3 <Destroy> {destroy .t2} bind .t2 <Destroy> {destroy .t1} bind .t1 <Destroy> {exit 0} destroy .t3 } set script [makeFile $code script] if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} { set error 1 } else { set error 0 } removeFile script list $error $msg ---- Result was: 1 {called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 {} ==== window-2.8 FAILED ==== window-2.11 Tk_DestroyWindow, don't reanimate a half-dead window FAILED ==== Contents of test case: set code [loadTkCommand] append code { toplevel .t1 toplevel .t2 update bind .t1 <Destroy> { if {[catch {entry .t2.newchild}]} { puts YES } else { puts NO } } bind .t2 <Destroy> {exit} destroy .t2 } set script [makeFile $code script] if {[catch {exec [interpreter] $script -geometry 10x10+0+0} msg]} { set error 1 } else { set error 0 } removeFile script list $error $msg ---- Result was: 1 {YES called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table called Tcl_FindHashEntry on deleted table} ---- Result should have been (exact matching): 0 YES ==== window-2.11 FAILED winfo.test ==== winfo-4.5 "winfo containing" command FAILED ==== Contents of test case: winfo containing [winfo rootx .t.f] [winfo rooty .t.f] ---- Result was: . ---- Result should have been (exact matching): .t.f ==== winfo-4.5 FAILED wm.test xmfbox.test Tests ended at Sun Aug 21 22:35:06 -0700 2005 all.tcl: Total 8617 Passed 7428 Skipped 1176 Failed 13 Sourced 86 Test Files. Files with failing tests: image.test safe.test text.test textWind.test winWm.test window.test winfo.test Number of tests skipped for each constraint: 7 altDisplay 16 colorsFree 20 defaultPseudocolor8 7 emptyTest 137 fonts 1 haveDISPLAY 5 haveOtherVisual 1 havePseudocolorVisual 7 knownBug 63 nonPortable 75 nonUnixUserInteraction 5 pseudocolor8 71 secureserver 4 stdio 1 tempNotPc 1 tempNotWin 5 testmenubar 6 testwrapper 674 unix 19 userInteraction 51 winSend ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-08-17 09:17 Message: Logged In: YES user_id=79902 Basically, the patch I did makes all the public functions in tkOldConfig.c treat the Tk_ConfigSpec parameters as 'const' data (unlike previously), which they do by creating per-interpreter copies. The per-interp copies are inherently thread-safe (or at least anything that comes a cropper is going to run into lots of other trouble too) and there is already a defined callback mechanism for ensuring that the per-interp copies get deleted at the right time. The reason for changing tkOldConfig.c as opposed to the clients of that code is that it makes *all* the users of the code (including extensions like BLT, Tix, etc.) safe from thread problems in this area of their code *without* modification. The alternative (making the callers manage per-thread copies of everything) spreads the maintenance effort much wider and is more complexity overall *anyway*. The whole assocData API should be treated as a way of having client code put their own fields in the Interp struct. Tk uses it in a number of places. In theory could use a per-thread copy instead of a per-interp copy, but I do not believe that the extra code (and maintenance complexity) to achieve this is warranted. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-08-17 04:41 Message: Logged In: YES user_id=113501 Well, I haven't seen dkf's patch for this bug (and the other associated bug 1247919); however, I am somewhat skeptical of the assocData idea. ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2005-08-16 12:58 Message: Logged In: YES user_id=72656 What remains outstanding then? Or is a full code review required? ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-08-16 10:36 Message: Logged In: YES user_id=79902 My patch has now been backported as well. Note that the other issues in this area (finalization ordering for one) have not been tackled by either patch. But patches to fix these issues should now be much smaller. ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2005-08-12 13:22 Message: Logged In: YES user_id=72656 Can the HEAD variant be applied for 8.4 as well? That seems to be the correct solution. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2005-08-12 11:26 Message: Logged In: YES user_id=79902 Fixed in HEAD using a different approach that will work with 3rd party code as well without modifications. Basically, it stores per-interpreter copies of all the Tk_ConfigSpec tables in Tcl's assocData stuff. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-07-31 22:32 Message: Logged In: YES user_id=113501 This new patch also fixes bug 1247919. These bugs are related because I found one while testing the fix for the other. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-07-25 06:37 Message: Logged In: YES user_id=113501 Attached patch totally fixes this bug (and 659129) and is fully threadsafe. Please review because after over two years, I would like to get it committed this week. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-07-25 02:30 Message: Logged In: YES user_id=113501 After doing some research, here is my overall plan to fix this bug: 1. Place all the configSpecs arrays into ThreadSpecificData for their corresponding files. 2. Each file that has a configSpecs array will have static CheckConfigSpecs and FreeConfigSpecsThreadExitProc functions to initialize and finalize their configSpecs array. 3. All places in the same file as the configSpecs array will be modified to use the CheckConfigSpecs function instead of using the static array. 4. All places in the Tk core where configSpecs is used outside of the file where it came from (like the Tk_ItemType structure, which is NOT thread specific) must be modified to call a function that will actually return the appropriate configSpecs for the calling thread. For item #4, I'm thinking about "adapting" the configSpecs pointer in the Tk_ItemType array (inside the Tk core only), to actually be a function pointer with a fixed prototype that will be used to object the configSpecs array. If this field is supposed to be used externally (outside the core), this change would require a TIP. In the future, to avoid similar traps, we need to be very careful about using any kind of static data when that data can be modified (or deleted, in this case) by multiple threads. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2005-07-25 01:12 Message: Logged In: YES user_id=113501 This bug still repros in HEAD. I think I'm going to take a crack at fixing it. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2004-06-22 07:04 Message: Logged In: YES user_id=113501 Still reproducible in HEAD. Makes Tk unusable in a multiple interp environment. ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2003-11-11 14:19 Message: Logged In: YES user_id=72656 This is likely to be addressed in the 8.5 timeframe. ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2003-11-11 03:04 Message: Logged In: YES user_id=113501 Any chance of this getting fixed? For 8.4.x? For 8.5? ---------------------------------------------------------------------- Comment By: Jeffrey Hobbs (hobbs) Date: 2003-07-16 18:57 Message: Logged In: YES user_id=72656 This may be related to Tk bug 659129 (Tk_Uids clean up incorrectly w/ threads) ---------------------------------------------------------------------- Comment By: Joe Mistachkin (mistachkin) Date: 2003-06-06 04:18 Message: Logged In: YES user_id=113501 At least one of the defValue fields from the configSpecs array (the one that is causing the error message) is trashed on delete of interp by: MSVCRTD! memset + 67 bytes Tcl_DeleteHashTable(Tcl_HashTable * 0x05840914) line 618 + 19 bytes FreeUidThreadExitProc(void * 0x00000000) line 508 + 19 bytes Tcl_FinalizeThread() line 929 + 12 bytes InterpreterThreadProc(void * 0x04e22c40) line 2750 + 13 bytes MSVCRTD! beginthreadex + 307 bytes KERNEL32! lstrcmpiW + 190 bytes ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=112997&aid=749908&group_id=12997 |