- priority: 5 --> 7
- assigned_to: nobody --> ghowlett
Hi,
We've an application that registers new Tcl_ObjType types w/ Tcl_RegisterObjType, and has C level tcl commands created using Tcl_CreateObjCommand.
When I invoke such commands while blt::watch is active, I realized that 'PostCmdProc' at bltWatch.c causes the Tcl_Obj::typePtr to be reset to NULL.
After doing some reading I've learned that Tcl_Obj has two representations ('string' and 'internal representation') and if one is retrieved, other one becomes invalid. I think these lines at PostCmdProc:
results = Blt_Strdup(Tcl_GetStringResult(interp));
Tcl_SetResult(interp, results, TCL_DYNAMIC);
are the problem. If it happens to obtain the result of a Tcl_Obj based commmand, the internal represenation of the returned Tcl_Obj becomes invalid since it requests the 'string' representation and therefore typePtr is becomes NULL.
I am not certainly sure if this is a bug in BLT or caused by something in our application but issue got resolved after i started to obtain the result in object way:
result_obj = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(result_obj);
results = Blt_Strdup(Tcl_GetString(result_obj));
and set the result accordingly:
Tcl_SetObjResult(interp,result_obj);
Tcl_DecrRefCount(result_obj);
diff -c output is below.
*** 242,248 ****
Tcl_DString buffer;
char string[200];
char *results;
- Tcl_Obj* result_obj = NULL;
register char **p;
char *retCode;
char *errorCode, *errorInfo;
--- 234,239 ----
*** 268,276 ****
if (errorCode != NULL) {
errorCode = Blt_Strdup(errorCode);
}
! result_obj = Tcl_GetObjResult(interp);
! Tcl_IncrRefCount(result_obj);
! results = Blt_Strdup(Tcl_GetString(result_obj));
}
--- 259,265 ----
if (errorCode != NULL) {
errorCode = Blt_Strdup(errorCode);
}
! results = Blt_Strdup(Tcl_GetStringResult(interp));
}
*** 323,330 ****
TCL_GLOBAL_ONLY);
Blt_Free(errorCode);
}
! Tcl_SetObjResult(interp,result_obj);
! Tcl_DecrRefCount(result_obj);
}
--- 309,315 ----
TCL_GLOBAL_ONLY);
Blt_Free(errorCode);
}
! Tcl_SetResult(interp, results, TCL_DYNAMIC);
}