Menu

#4783 Tcl_EvalObjv has two types of crashes

obsolete: 8.5.9
closed-invalid
5
2011-01-25
2011-01-25
No

Tested on Linux:
Linux XXX YYYY #5 SMP Mon Nov 16 15:30:32 PST 2009 x86_64 x86_64 x86_64 GNU/Linux

Compiled tcl8.5.9 like this:
configure --prefix=/home/sehmann/tcltk-8.5.9 --enable-shared --enable-64bit --enable-symbols
make install

These problems do not occur on tcl8.4.9, we are trying to upgrade and this is a blocker.

Case 1) This is the case for my application
C code:
Tcl_Obj* cmdArgs[3];
cmdArgs[0] = Tcl_NewStringObj("::testtest", -1);
cmdArgs[1] = Tcl_NewStringObj("::testtest2", -1);
cmdArgs[2] = Tcl_NewIntObj(1);
int result = Tcl_EvalObjv(interp, 3, cmdArgs, TCL_EVAL_GLOBAL);

TCL code:
proc testtest2 {} {
error "this is a test error"
}

proc testtest {foo bar} {
$foo
}

Gives:
Error message:
UpdateStringProc should not be invoked for type cmdName
Program received signal SIGABRT, Aborted.

Stack trace:
#0 0x0000003eb752e21d in raise () from /lib64/tls/libc.so.6
#1 0x0000003eb752fa1e in abort () from /lib64/tls/libc.so.6
#2 0x00007ffff7e85a7d in Tcl_PanicVA (format=0x7ffff7ed4870 "UpdateStringProc should not be invoked for type %s", argList=0x7fffffff9c60)
at /home/sehmann/tcl8.5.9/unix/../generic/tclPanic.c:103
#3 0x00007ffff7e85b57 in Tcl_Panic (format=0x7ffff7ed4870 "UpdateStringProc should not be invoked for type %s")
at /home/sehmann/tcl8.5.9/unix/../generic/tclPanic.c:132
#4 0x00007ffff7e82d94 in Tcl_GetStringFromObj (objPtr=0x170c5b0, lengthPtr=0x7fffffff9da4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1626
#5 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#6 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7fffffff9e7c)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#7 0x00007ffff7de411d in Tcl_EvalObjv (interp=0x504640, objc=3, objv=0x7fffffff9f10, flags=131072)
at /home/sehmann/tcl8.5.9/unix/../generic/tclBasic.c:3919

Case 2) This is disturbing
C code:
Tcl_Obj* cmdArgs[3];
cmdArgs[0] = Tcl_NewStringObj("::testtest", -1);
cmdArgs[1] = Tcl_NewStringObj("::testtest2", -1);
cmdArgs[2] = Tcl_NewIntObj(1);
int result = Tcl_EvalObjv(interp, 3, cmdArgs, TCL_EVAL_GLOBAL);

TCL code:
proc testtest2 {} {
error "this is a test error"
}

proc testtest {foo bar} {
testtest2
}

Gives:
Error message:
Program received signal SIGSEGV, Segmentation fault.

Stack trace (infinite recursion):
#0 0x00007ffff7e73c47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1848
#1 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc40a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#2 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#3 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc41a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#4 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#5 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc42a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#6 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#7 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc43a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#8 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#9 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc44a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#10 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#11 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc45a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#12 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#13 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc46a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#14 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#15 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc47a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#16 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#17 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc48a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629
#18 0x00007ffff7e73d47 in UpdateStringOfList (listPtr=0xec4dd0) at /home/sehmann/tcl8.5.9/unix/../generic/tclListObj.c:1872
#19 0x00007ffff7e82da6 in Tcl_GetStringFromObj (objPtr=0xec4dd0, lengthPtr=0x7ffffdfc49a4)
at /home/sehmann/tcl8.5.9/unix/../generic/tclObj.c:1629

Discussion

  • miguel sofer

    miguel sofer - 2011-01-25

    There is a is pilot error: the elements in objv should have a reference count maintained by the caller. Do
    for (i=0; i<3; i++) {
    Tcl_IncrRefCount(cmdArgs[i]);
    }
    Tcl_EvalObjv((interp, 3, cmdArgs, TCL_EVAL_GLOBAL);
    for (i=0; i<3; i++) {
    result = Tcl_DecrRefCount(cmdArgs[i]);
    }

    Does this fix the problem?

     
  • miguel sofer

    miguel sofer - 2011-01-25
    • status: open --> pending-invalid
     
  • miguel sofer

    miguel sofer - 2011-01-25

    Oops ... this box is bad for editing, isn't it? Make it

    or (i=0; i<3; i++) {
    Tcl_IncrRefCount(cmdArgs[i]);
    }
    result = Tcl_EvalObjv((interp, 3, cmdArgs, TCL_EVAL_GLOBAL);
    for (i=0; i<3; i++) {
    Tcl_DecrRefCount(cmdArgs[i]);
    }

     
  • Stephen Ehmann

    Stephen Ehmann - 2011-01-25

    This works, thanks Miguel!
    I can see if any Tcl internals do:
    incr
    do something
    decr
    then the object will get deleted so I need to incr/decr to make sure it survives to the end of the call. Is there any document describing this? All the tcl docs I have looked at so far have not highlighted this sort of point.

     
  • Stephen Ehmann

    Stephen Ehmann - 2011-01-25
    • status: pending-invalid --> open-invalid
     
  • miguel sofer

    miguel sofer - 2011-01-25

    The man page http://tcl.tk/man/tcl8.5/TclLib/Eval.htm says: "The caller of Tcl_EvalObjv has to manage the reference count of the elements of objv, insuring that the objects are valid until Tcl_EvalObjv returns."

    Conceded, the point was not stressed in the 8.4 man page.

     
  • miguel sofer

    miguel sofer - 2011-01-25
    • status: open-invalid --> closed-invalid