Menu

#2261 window-2.9 deadlocks threaded Tk

obsolete: 8.6b1
pending-fixed
69. Events (88)
8
2013-03-26
2007-05-09
No

The test window-2.9 deadlocks threaded TkX11 and TkAqua (only generic code appears to be involved). Backtrace from TkX11 attached.
The test succeeds in the unthreaded build.

window-2.9 runs the following in a subprocess:
toplevel .t1
toplevel .t2
update
bind .t2 <Destroy> {puts "Destroy .t2" ; exit 1}
bind .t1 <Destroy> {puts "Destroy .t1" ; exit 0}
destroy .t2

the deadlock occurs because Tcl_Finalize() is entered recursively, first from the [exit] in the .t2 <Destroy> handler, where it calls TkFinalizeThread(), which destroys all windows and causes the .t1 <Destroy> handler to fire, leading to a nested [exit] and deadlock on TclpInitLock() in Tcl_Finalize().

Discussion

  • Daniel A. Steffen

    gdb backtrace of window-2.9 deadlock

     
  • Don Porter

    Don Porter - 2007-05-09

    Logged In: YES
    user_id=80530
    Originator: NO

    Dup. of 740570 ?

     
  • Daniel A. Steffen

    Logged In: YES
    user_id=90580
    Originator: YES

    indeed a dup of 740570, apologies.

    The analysis there and in 870281 seem to look at the wrong process though, the backtrace here is from the subprocess where the snippet above runs (which is where the deadlock occurs).
    The hang can be reproduced simply by running the code above in a threaded tktest, so there is no involvment of exec/fork/signals as theorized in 740570.

    The problem is definitely caused by nested invocation of [exit] from the <Destroy> handlers; not sure how to go about a fix in Tk, DestroyNotify events explicitly ignore TK_ALREADY_DEAD...

    The easiest option might be to check inFinalize before setting it in Tcl_Finalize(), or equivalently, to check TclInExit() in Tcl_Exit() before calling Tcl_Finalize(), but I don't understand tcl finalization well enough to know if that would have undesireable effects.

     
  • Daniel A. Steffen

    Logged In: YES
    user_id=90580
    Originator: YES

    indeed a dup of 740570, apologies.

    The analysis there and in 870281 seem to look at the wrong process though, the backtrace here is from the subprocess where the snippet above runs (which is where the deadlock occurs).
    The hang can be reproduced simply by running the code above in a threaded tktest, so there is no involvment of exec/fork/signals as theorized in 740570.

    The problem is definitely caused by nested invocation of [exit] from the <Destroy> handlers; not sure how to go about a fix in Tk, DestroyNotify events explicitly ignore TK_ALREADY_DEAD...

    The easiest option might be to check inFinalize before setting it in Tcl_Finalize(), or equivalently, to check TclInExit() in Tcl_Exit() before calling Tcl_Finalize(), but I don't understand tcl finalization well enough to know if that would have undesireable effects.

     
  • Don Porter

    Don Porter - 2007-05-09

    Logged In: YES
    user_id=80530
    Originator: NO

    I don't have all the details
    straight in my head anymore without
    digging into the logs for a good
    review, but I do recall that we've
    gotten Tk finalization matters wrong
    at least a couple of different ways
    already, so much care and much testing
    are in order as we move forward with
    this one.

     
  • Daniel A. Steffen

    • milestone: --> obsolete: 8.6b1
    • priority: 5 --> 8
     
  • Daniel A. Steffen

    now added a constraint to bypass window-2.9 in threaded builds

    raising prio, would be desirable to resolve the deadlock from nested invocations of Tcl_Finalize() for 8.6

     
  • Don Porter

    Don Porter - 2013-03-26

    This is fixed in 8.6. Presumably a consequence
    of the reworking of Tcl finalization.

    Removed the constraint from the test.

    Still buggy on older branches. Seems destined
    to be a forever "Won't Fix" there.

     
  • Don Porter

    Don Porter - 2013-03-26
    • status: open --> pending-fixed
     
MongoDB Logo MongoDB