For Programmers: Free Programming Magazines  


Home > Archive > Tcl > April 2005 > reference count in Tcl_LinkVar









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author reference count in Tcl_LinkVar
tse.eric@gmail.com

2005-04-26, 4:02 am

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

Jeff Hobbs

2005-04-26, 4:02 am

tse.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
tse.eric@gmail.com

2005-04-27, 8:59 pm

Who 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...894&atid=110894

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com