Mem corruption, detected by andrewsh
mig@T510:~/DEVEL/tcl-core/trunk/unix$ cat /tmp/test.tcl
for {set i 0} {$i < 5} {incr i} {
catch {catch {source foo} puts $::errorInfo}
}
puts DONE
mig@T510:~/DEVEL/tcl-core/trunk/unix$ ./tclsh /tmp/test.tcl
*** glibc detected *** ./tclsh: invalid fastbin entry (free): 0x0000000001e67430 ***
The problem is with $::errorInfo, the script runs without crashing if we put $::nothing instead
Valgrind sees the crash at line 364 in tclCmdAH.c: there is a decrRefCount of the 'options' Tcl_Obj which was already freed from Tcl_ObjSetVar2 in the line above.
Tcl_ObjSetVar2 is "fire and forget" with respect to the newValuePtr - it will clear a Tcl_Obj with 0 reference count. This means that line 364 is wrong, it should not be there at all.
Fixed in trunk.
The ::errorInfo in the demo really clouds the issue.
Here's the simplified bug demo that gets to the heart of
the matter:
catch {} -> noSuchNs::var
And the worse counterpart:
catch error -> noSuchNs::var
In line 359:
if (objc == 4 ) {
Shouldn't that be:
if (result == TCL_ERROR && objc == 4 ) {
The Tcl_GetReturnOptions() function should
only be called if the script returned an error, isn't it?
This appears to fix the crash.
Regards,
Jan Nijtmans
B.T.W.: Tcl 8.5 has the same bug, only the
given lines are in Tcl_CatchObjCmd (tclCmdAH.c lines 273/276)
So it's not an NRE bug, It's a TIP #280 implementation bug ;-)
Regards,
Jan Nijtmans
The options dictionary variable gets set
for all return codes.
Fixed on 8.5 and 8.6 branches