#2582 Segmentation fault returning value in Thread for Thread 2.5

final: 8.3.5
closed
7
2014-09-07
2004-01-26
Rob Ratcliff
No

I wrote a simple "exec" function that runs the
specified program in another thread, splits out the
stdout and
stderr output and returns asynchronously.
(I attached the script and traceback from the core dump
at the end of this message.)

I started off using Tcl 8.3.5/Thread 2.5 (2.1.5). It
seems that if the script running in the
other thread returns a value using "return $result", I
get a core dump. But, if I return the
value using "set result", it doesn't core dump.

If I use Tcl 8.4.5/Thread 2.5.2, the script throws an
error condition if I use
"return $result", but not if I use "set result". It
should not be throwing
an error condition. (It doesn't matter whether the
print.tcl prints to
stderr, it happens when only stdout is printed as well.)

Thanks,

Rob

test.tcl
#!/bin/csh -f

# comment out next line \ exec tclsh8.3 $9 $argv:q
#exec tclsh8.4 $9 $argv:q

package require Thread

namespace eval DE {

proc threadError { threadid errorInfo } {
global DE::threadError
set threadError 1
return $threadError
}

proc texec { args } {
global DE::thread DE::threadError
errorInfo errorCode
global result

set DE::threadError 0

set thread [thread::create]
thread::errorproc DE::threadError

set script {
set result ""
set filename tmp_[pid]

set errorCheck 0
set errorCheck [ catch { eval
exec $program 2> $filename } result ]

set lines ""
if { $errorCheck > 0 } {
set FILE [open $filename r]
set lines [read $FILE
[file size $filename]]
close $FILE
file delete $filename
error "$lines"
} else {
file delete $filename
#set output
}
set result [list $result $lines
$errorCheck]

#set result; # this works
return $result ; # this doesn't
}

thread::send -async $thread "set program
\"$args\"; $script" result

vwait result

if { $DE::threadError != 0 } {
error "Error executing command
$args:\n$result\n$errorInfo"
}

if { [string length [lindex $result 1]]
!= 0 } {
puts stderr [lindex $result 1]
}

return [lindex $result 0]
}

}

if { 1 } {
catch {
puts [DE::texec ./print.tcl]
} output
puts "$output"
}

-------------------- file print.tcl
-----------------------------------------------------

#!/bin/csh

# comment \ exec tclsh $9 $*

puts stdout "message from stdout"
puts stderr "message from stderr"
#error "throw an error"

-------------------------------------- Traceback
-----------------------------------

Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show
warranty" for details.
This GDB was configured as "i386-redhat-linux"...
Core was generated by `tclsh8.3 test.tcl'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from
/fltapps/opt/mdopt/3dopt/Linux-2/lib/libtcl8.3g.so...done.
Loaded symbols for
/fltapps/opt/mdopt/3dopt/Linux-2/lib/libtcl8.3g.so
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libpthread.so.0...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from
/fltapps/opt/mdopt/3dopt/Linux-2/lib/thread2.5/libthread2.5g.so...done.
Loaded symbols for
/fltapps/opt/mdopt/3dopt/Linux-2/lib/thread2.5/libthread2.5g.so
#0 0x40184e27 in strlen () from /lib/libc.so.6
(gdb) where
#0 0x40184e27 in strlen () from /lib/libc.so.6
#1 0x4008ed9d in Tcl_NewStringObj (bytes=0x726f7272
<Address 0x726f7272 out of bounds>, length=-1)
at ../generic/tclStringObj.c:167
#2 0x4009638d in Tcl_SetVar2 (interp=0x804cd50,
part1=0x400cea27 "errorCode", part2=0x0,
newValue=0x726f7272 <Address 0x726f7272 out of
bounds>, flags=1) at ../generic/tclVar.c:1079
#3 0x40096362 in Tcl_SetVar (interp=0x804cd50,
varName=0x400cea27 "errorCode",
newValue=0x726f7272 <Address 0x726f7272 out of
bounds>, flags=1) at ../generic/tclVar.c:1026
#4 0x400c39d2 in ThreadClbkSetVar (interp=0x804cd50,
clientData=0x807d4b8) at generic/threadCmd.c:1379
#5 0x400c5889 in ThreadEventProc (evPtr=0x80831a8,
mask=-3) at generic/threadCmd.c:2626
#6 0x4007eb62 in Tcl_ServiceEvent (flags=-3) at
../generic/tclNotify.c:607
#7 0x4007ee52 in Tcl_DoOneEvent (flags=-3) at
../generic/tclNotify.c:846
#8 0x400590db in Tcl_VwaitObjCmd (clientData=0x0,
interp=0x804cd50, objc=2, objv=0x804f268)
at ../generic/tclEvent.c:990
#9 0x40059e7f in TclExecuteByteCode (interp=0x804cd50,
codePtr=0x8073b68) at ../generic/tclExecute.c:877
#10 0x40036cb7 in Tcl_EvalObjEx (interp=0x804cd50,
objPtr=0x8071ce8, flags=0) at ../generic/tclBasic.c:2733
#11 0x4008ab2e in TclObjInterpProc
(clientData=0x8073e40, interp=0x804cd50, objc=2,
objv=0x804f260)
at ../generic/tclProc.c:1001
#12 0x40059e7f in TclExecuteByteCode (interp=0x804cd50,
codePtr=0x8073538) at ../generic/tclExecute.c:877
#13 0x40036cb7 in Tcl_EvalObjEx (interp=0x804cd50,
objPtr=0x80696e0, flags=0) at ../generic/tclBasic.c:2733
#14 0x4003b74b in Tcl_CatchObjCmd (dummy=0x0,
interp=0x804cd50, objc=3, objv=0x804f250)
at ../generic/tclCmdAH.c:264
#15 0x40059e7f in TclExecuteByteCode (interp=0x804cd50,
codePtr=0x8073438) at ../generic/tclExecute.c:877
#16 0x40036cb7 in Tcl_EvalObjEx (interp=0x804cd50,
objPtr=0x8071e38, flags=0) at ../generic/tclBasic.c:2733
#17 0x4003f20a in Tcl_IfObjCmd (dummy=0x0,
interp=0x804cd50, objc=3, objv=0xbfffe770)
at ../generic/tclCmdIL.c:240
#18 0x4008189b in EvalObjv (interp=0x804cd50, objc=3,
objv=0xbfffe770,
command=0x805e030 "\nif { 1 } {\n\tcatch {\n\t\t
puts [DE::texec ./print.tcl]\n\t} output\n\tputs
\"$output\"\n}\n", length=81, flags=0) at
../generic/tclParse.c:932
#19 0x40082162 in Tcl_EvalEx (interp=0x804cd50,
script=0x805db38 "#!/bin/tcsh -f\n\n# comment out
next line \\\nexec tclsh8.3 $9 $argv:q\n#exec tclsh8.4
$9 $argv:q\n\npackage require Thread\n\nnamespace eval
DE {\n\n\tproc threadError { threadid errorInfo }
{\n\t\tglobal DE::threa"..., numBytes=1353, flags=0) at
../generic/tclParse.c:1393
#20 0x40076206 in Tcl_EvalFile (interp=0x804cd50,
fileName=0xbfffec1c "test.tcl")
at ../generic/tclIOUtil.c:323
#21 0x40079d81 in Tcl_Main (argc=1, argv=0xbfffede8,
appInitProc=0x80486b6 <Tcl_AppInit>)
at ../generic/tclMain.c:227
#22 0x080486ac in main (argc=2, argv=0xbfffede4) at
../unix/tclAppInit.c:99
#23 0x401221c4 in __libc_start_main () from /lib/libc.so.6
(gdb)

Discussion

  • Rob Ratcliff
    Rob Ratcliff
    2004-01-29

    Test program that demonstrates the segmentation fault on Linux

     
    Attachments
  • Rob Ratcliff
    Rob Ratcliff
    2004-01-29

    Program exec'd by test.tcl

     
    Attachments
  • Rob Ratcliff
    Rob Ratcliff
    2004-01-29

    • priority: 5 --> 7
     
  • Logged In: YES
    user_id=95086

    This is a Tcl8.3.5 issue. The 8.4+ does not core
    so I'm closing this.
    However, this bug exposed another one in the threading
    extension and I have corrected that one in the thread
    tree. The thing was that we were wrongly triggering
    error at executing scripts which contained [return]
    command as the last command in the script. This is not
    compatible to the way Tcl is doing things so I've
    changed the behaviour to always return the result code
    as-is to caller and trigger error only for TCL_ERROR
    return code.

     
    • status: open --> closed