Code Comments
Programming Forum and web based access to our favorite programming groups.Hi guys,
for Tcl 8.4.x version, I got a freeing object which has -1 refernce
count (using TCL_DEBUG_MEM compilation flag) and traced to
Tcl_LinkVar():
int
Tcl_LinkVar(interp, varName, addr, type)
Tcl_Interp *interp; /* Interpreter in which varName exists.
*/
CONST char *varName; /* Name of a global variable in interp.
*/
char *addr; /* Address of a C variable to be linked
* to varName. */
int type; /* Type of C variable: TCL_LINK_INT,
etc.
* Also may have TCL_LINK_READ_ONLY
* OR'ed in. */
{
Tcl_Obj *objPtr;
Link *linkPtr;
int code;
linkPtr = (Link *) ckalloc(sizeof(Link));
linkPtr->interp = interp;
linkPtr->varName = Tcl_NewStringObj(varName, -1);
Tcl_IncrRefCount(linkPtr->varName);
linkPtr->addr = addr;
linkPtr->type = type & ~TCL_LINK_READ_ONLY;
if (type & TCL_LINK_READ_ONLY) {
linkPtr->flags = LINK_READ_ONLY;
} else {
linkPtr->flags = 0;
}
objPtr = ObjValue(linkPtr);
// LINE A: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, objPtr,
TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
Tcl_DecrRefCount(linkPtr->varName);
Tcl_DecrRefCount(objPtr);
// LINE B: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ckfree((char *) linkPtr);
return TCL_ERROR;
}
Should we add in LINE A:
Tcl_IncrRefCount(objPtr);
because ObjValue(linkPtr) is not incrementing the reference count and
objPtr is decr count in line B
Thanks,
ERic
Post Follow-up to this messagetse.eric@gmail.com wrote:
> for Tcl 8.4.x version, I got a freeing object which has -1 refernce
> count (using TCL_DEBUG_MEM compilation flag) and traced to
> Tcl_LinkVar():
This is a "bug" in 8.4 and HEAD. However, after tracing
through the code, doing DecrRefCount on the new object
shouldn't throw an error. Can you be more specific on
how you invoke the call sequence that gives you a NULL?
For TCL_MEM_DEBUG, Tcl_DbDecrRefCount will be called, and
it will move ref count to -1, the TclFreeObj it. That
only panics if the ref count is < -1 (== -1 is "ok"). So
did you receive a panic, or did the -1 ref count seem
incorrect? The incr ref count is appropriate, but I'd
like to specifically understand the error received. Note
that in general, the Tcl_IncrRefCount is not actually
correct below, as Tcl_ObjSetVar2 will incr the ref count
of what you pass in (or similar effect, depending on the
set flags).
> int
> Tcl_LinkVar(interp, varName, addr, type)
...
> {
> Tcl_Obj *objPtr;
> Link *linkPtr;
> int code;
>
> linkPtr = (Link *) ckalloc(sizeof(Link));
> linkPtr->interp = interp;
> linkPtr->varName = Tcl_NewStringObj(varName, -1);
> Tcl_IncrRefCount(linkPtr->varName);
> linkPtr->addr = addr;
> linkPtr->type = type & ~TCL_LINK_READ_ONLY;
> if (type & TCL_LINK_READ_ONLY) {
> linkPtr->flags = LINK_READ_ONLY;
> } else {
> linkPtr->flags = 0;
> }
> objPtr = ObjValue(linkPtr);
> // LINE A: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> if (Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, objPtr,
> TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
> Tcl_DecrRefCount(linkPtr->varName);
> Tcl_DecrRefCount(objPtr);
> // LINE B: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ckfree((char *) linkPtr);
> return TCL_ERROR;
> }
>
> Should we add in LINE A:
>
> Tcl_IncrRefCount(objPtr);
>
> because ObjValue(linkPtr) is not incrementing the reference count and
> objPtr is decr count in line B
--
Jeff Hobbs, The Tcl Guy
http://www.ActiveState.com/, a division of Sophos
Post Follow-up to this messageWho whom may be interested. Jeff and I found out how to reproduce this bug and I have reported it to: http://sourceforge.net/tracker/inde...r /> id=110894
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.