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 |