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
| |
|
|
|
|
|