Menu

#26 tclx wait command hangs with tcl8.4 compiled with threads

open
nobody
None
6
2004-11-23
2003-06-04
No

The TclX wait command hangs after a fork if the following
conditions are met:

- TclX is loaded on tclsh8.4

- Tcl and TclX are compiled with --enable-threads.

- a fork is done but no execl is done and the
child exits

- the parent process issues a wait on the child pid

The bug can be easily reproduced with the following tcl
script:

package require Tclx 8.4
echo "using tcl $tcl_version + tclx [infox version]"

proc make_process {program {args {}}} {
echo "forking $program"
flush stdout; flush stderr
set pid [fork]
if {$pid == 0} {
catch {execl $program $args}
exit 1
} else {
return $pid
}
}

# cmdtrace on
set pid [make_process /bin/true]
puts -nonewline "waiting $pid ... "; flush stdout
puts [wait $pid]

set pid [make_process /some_bad_program]
puts -nonewline "waiting $pid ... "; flush stdout
puts [wait $pid]

The problem doesn't happen with Tcl8.3 or when Tcl and
TclX are
both compiled without thread support, as is the case of
ActiveTcl.

The problem seems to be in the exit of the child but
the visible
effect is that the wait in the parent hangs forever.

An strace of the processes (see attachment) shows that
when the
child process exits it sends a 'q' command to a thread
belonging to
the parent and then it probably waits a signal back
from the parent
to terminate. As the parent doesn't know how to handle
this message
the child hangs forever and the wait in the parent will
never return.

--
Massimo Dal Zotto <dz@debian.org>

Discussion

  • Massimo Dal Zotto

    strace log of the problem

     
  • David N. Welton

    David N. Welton - 2003-06-09

    Logged In: YES
    user_id=240

    I get Tcl to crash with this simple bit of code:
    package require Tclx
    for {set i 0} {$i < 5} {incr i} {
    set pid [fork]
    if { $pid == 0 } {
    break
    } else {
    puts $pid
    }
    }

    tclsh8.4 [~/tmp]puts $tcl_patchLevel
    8.4.2

    Using the latest Tclx code.

     
  • David N. Welton

    David N. Welton - 2003-06-09

    Logged In: YES
    user_id=240

    Here is what happens with my code:

    @ashland [~/tmp] $ ./forkthreadserver.tcl
    30328
    30329
    30330
    30331
    Tcl_FinalizeNotifier: notifier pipe not initialized
    Tcl_FinalizeNotifier: notifier pipe not initialized
    Tcl_FinalizeNotifier: notifier pipe not initialized
    30332
    Tcl_FinalizeNotifier: notifier pipe not initialized
    Aborted (core dumped)

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2004-11-23
    • priority: 5 --> 6
     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2004-11-23

    Logged In: YES
    user_id=72656

    This is actually a core issue with handling of fork with
    threads. The two are simply contradictory, and you have to
    do all sorts of pthread magic to get them to behave. See
    Tcl core bug 749639.

     
  • Massimo Dal Zotto

    Logged In: YES
    user_id=189001

    Since most of tcl programs don't use threads would it be
    possible to have
    thread support compiled in but disabled by default and
    enabled at runtime
    with a command line switch? Something like:

    $ tclsh non-threaded-app.tcl
    $ tclsh -enable-threads threaded-app.tcl

    Another possibility would be an enable_threads command which
    would be
    called automatically by the tcl thread library during
    initialization.

     

Log in to post a comment.