Tcl Source Code

View Ticket
Login
Ticket UUID: 884549
Title: Segmentation fault returning value in Thread for Thread 2.5
Type: Bug Version: final: 8.3.5
Submitter: wobster Created on: 2004-01-26 04:46:42
Subsystem: 80. Thread Package Assigned To: vasiljevic
Priority: 7 High Severity:
Status: Closed Last Modified: 2004-01-31 21:26:13
Resolution: None Closed By: vasiljevic
    Closed on: 2004-01-31 14:26:13
Description:
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)
User Comments: vasiljevic added on 2004-01-31 21:26:13:
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.

wobster added on 2004-01-29 09:39:49:

File Added - 75065: print.tcl

wobster added on 2004-01-29 09:38:54:

File Added - 75064: test.tcl

Attachments: