From: SourceForge.net <no...@so...> - 2012-01-18 23:45:14
|
Bugs item #3475569, was opened at 2012-01-18 08:37 Message generated for change (Comment added) made by sebres You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=3475569&group_id=10894 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 10. Objects Group: current: 8.5.11 Status: Open Resolution: None Priority: 8 Private: No Submitted By: sebres (sebres) Assigned to: Donal K. Fellows (dkf) Summary: Unexpected behavior / Panic / Tcl_Obj deletion management Initial Comment: Platform: ANY; Area: Tcl core, DeletePending; I have an unexpected behavior, that can be reproduced only if an Tcl_Obj will be destroyed (in a freeIntRepProc of this) - also ObjDeletePending(contextPtr) is true. By call of TclFSNormalizeAbsolutePath through "link = Tcl_FSLink(retVal, NULL, 0);", the retVal will be shared obj (refCount = 2), hereafter by call "Tcl_SetObjLength(retVal, ...);" a PANIC ("Tcl_SetObjLength called with shared object"), hereafter folowing Exception, access vio etc. The problem is Tcl_FSJoinToPath(pathPtr,...), that incr refCount of object "pathPtr" after that called. I have attached a patch, that i created to work around problem. In addition the simple code, that will be correctly executed "normally" and perfect unexpected panic in "DeletePending" mode: <code> Tcl_Obj * obj; Tcl_Obj * list; Tcl_Obj * ret; // brand new obj obj = Tcl_NewListObj(0, NULL); Tcl_IncrRefCount(obj); // brand new parent list = Tcl_NewListObj(1, &obj); Tcl_IncrRefCount(list); // ... here anything else ... // // delete parent ... Tcl_DecrRefCount(list); // here obj->refCount should be 1 (and normally also 1), but in "DeletePending" mode it is 2 ... // also here BOOM if DeletePending : Tcl_SetObjLength(obj, 0); // ... here anything else ... // // delete object Tcl_DecrRefCount(obj); </code> In my opinion, the DeletePending mechanism must be changed, for example using "Epoch" in Obj struct (the objects created in DeletePending mode could be deleted directly without PushObjToDelete) ... Or completelly removed from core. On every case, all tcl tests should be extended to check it in DeletePending mode. ---------------------------------------------------------------------- >Comment By: sebres (sebres) Date: 2012-01-18 15:45 Message: I'm trying to describe it with other words. In my own tcl obj type X, i have call in the freeIntRepProc of type X somthing like this: file normalize {D:\test\bin\..\modules\tcl\lib\tcl8.5\encoding\cp1252.enc}. Indirectly, cause something like following was called: encoding convertto $enc "text here" This was very hard to find and reproduce, cause error occured only when "$enc" was not yet loaded, and by NOT normalized "tcl_library" path. (In debugger was normalized path). The problem was a loading of encoding file, and ultimately, the bug is TclFSNormalizeAbsolutePath / Tcl_FSLink / Tcl_FSJoinToPath. And of course only if OnDeletePending is true. See my both attached patches. ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2012-01-18 11:50 Message: Passing to dkf in case he's free to look sooner than I am. I'll pick it up again when I'm free if nobody else gets it done by then. ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2012-01-18 10:47 Message: Indeed - ANY in-place modification of a Tcl_Obj requires inquiring about the shared status. The problem about "knowing" the refCount is that you don't always know, as in the present case where you knew something that as a matter of fact is not true. Note that your // ... here anything else ... // could contain refCount changes too, like storing the thing in a variable or ... anything else. dgp: reassigning to you as a request for a second independent opinion on the matter. ---------------------------------------------------------------------- Comment By: sebres (sebres) Date: 2012-01-18 10:29 Message: please read carefully my example code. i know what shared object is. the exception resp. panic occured standalone in tcl core also, like call of this in freeIntRepProc (by DeletePending) : file normalize {D:\test\bin\..\modules\tcl\lib\tcl8.5\init.tcl}. in my example code (if you read carefully) ... before call of Tcl_SetObjLength(obj, 0) the refCount should be "1", and is "1" normally, but by DeletePending it is "2". Or you want to tell me - you write before each modification call this : <code> if (Tcl_IsShared(retVal)) { TclDecrRefCount(retVal); retVal = Tcl_DuplicateObj(retVal); TclIncrRefCount(retVal); } </code> I do it so, but only by object, which refCount i don't know. In my example refCount of "obj" should be definitely "1". Otherwise the tcl8.5 code should be also completelly revised. ---------------------------------------------------------------------- Comment By: miguel sofer (msofer) Date: 2012-01-18 08:56 Message: Looks like a bug in your own code, PANIC ("Tcl_SetObjLength called with shared object") is the clue: you should never try to modify a shared object. The proper way is to check using Tcl_IsShared(), and obtain if necessary your own copy with Tcl_DuplicateObj(). Now: if this is being done within Tcl and not by your code, it is definitely Tcl's bug. In that case please provide sample code that triggers the panic. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=3475569&group_id=10894 |