Re: Hidden diversion - "Nested Tcl_Obj deletion management support"

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Hidden diversion - "Nested Tcl_Obj deletion management support"

A.Mitrohin
On Sun, Jun 25, 2017 at 07:13:32PM -0400, Donald Porter wrote:
>
> > On Jun 25, 2017, at 2:45 PM, foo via Tcl-Core <[hidden email]> wrote:
> > This code breaks my program.
>
> The code you quoted does not appear in any current release
> of Tcl.
>
See below.

> Please check whether your program is happier with our current
> release, Tcl 8.6.6.  If absolutely necessary, you might also try
> Tcl 8.5.19.  The last time Tcl looked somewhat like what you
> quoted appears to be 8.5.17 or 8.6.3 in 2014.

[root@foo ~]# pkg info tcl86
tcl86-8.6.6_2
Name           : tcl86
Version        : 8.6.6_2
Installed on   : Sun Jun 25 20:42:52 2017 +07
Origin         : lang/tcl86
Architecture   : FreeBSD:11:amd64
Prefix         : /usr/local
Categories     : lang
Licenses       : TclTk
Maintainer     : [hidden email]
WWW            : http://www.tcl.tk/
Comment        : Tool Command Language
Options        :
        DEBUG          : on
        DTRACE         : on
        MODULES        : on
        TCLMAN         : on
        THREADS        : on
        TZDATA         : on
Shared Libs provided:
        libtcl86.so.1
Annotations    :
Flat size      : 23.5MiB
Description    :
This is Tcl version 8.6, an embeddable tool command language.

Tcl (Tool Command Language) is a very powerful but easy to learn dynamic
programming language, suitable for a very wide range of uses, including web
and desktop applications, networking, administration, testing and many more.
Open source and business-friendly, Tcl is a mature yet evolving language that
is truly cross platform, easily deployed and highly extensible.

A full set of manual pages is also provided with this port.

WWW: http://www.tcl.tk/


~$ vim +1417 generic/tclObj.c

1417 void
1418 TclFreeObj(
1419     register Tcl_Obj *objPtr)   /* The object to be freed. */
1420 {
1421     /*
1422      * Invalidate the string rep first so we can use the bytes value for our
1423      * pointer chain, and signal an obj deletion (as opposed to shimmering)
1424      * with 'length == -1'.
1425      */
1426
1427     TclInvalidateStringRep(objPtr);
1428     objPtr->length = -1;
1429
1430     if (!objPtr->typePtr || !objPtr->typePtr->freeIntRepProc) {
1431         /*
1432          * objPtr can be freed safely, as it will not attempt to free any
1433          * other objects: it will not cause recursive calls to this function.
1434          */
1435
1436         TCL_DTRACE_OBJ_FREE(objPtr);
1437         TclFreeObjStorage(objPtr);
1438         TclIncrObjsFreed();
1439     } else {
1440         /*
1441          * This macro declares a variable, so must come here...
1442          */
1443
1444         ObjInitDeletionContext(context);
1445
1446         if (ObjDeletePending(context)) {
1447             PushObjToDelete(context, objPtr);
1448         } else {
1449             /*
1450              * Note that the contents of the while loop assume that the string
1451              * rep has already been freed and we don't want to do anything
1452              * fancy with adding to the queue inside ourselves. Must take care
1453              * to unstack the object first since freeing the internal rep can
1454              * add further objects to the stack. The code assumes that it is
1455              * the first thing in a block; all current usages in the core
1456              * satisfy this.
1457              */
1458
1459             TCL_DTRACE_OBJ_FREE(objPtr);
1460             ObjDeletionLock(context);
1461             objPtr->typePtr->freeIntRepProc(objPtr);
1462             ObjDeletionUnlock(context);
1463
1464             TclFreeObjStorage(objPtr);
1465             TclIncrObjsFreed();
1466             ObjDeletionLock(context);
1467             while (ObjOnStack(context)) {
1468                 Tcl_Obj *objToFree;
1469
1470                 PopObjToDelete(context, objToFree);
1471                 TCL_DTRACE_OBJ_FREE(objToFree);
1472                 if ((objToFree->typePtr != NULL)
1473                         && (objToFree->typePtr->freeIntRepProc != NULL)) {
1474                     objToFree->typePtr->freeIntRepProc(objToFree);
1475                 }
1476                 TclFreeObjStorage(objToFree);
1477                 TclIncrObjsFreed();
1478             }
1479             ObjDeletionUnlock(context);
1480         }
1481     }
1482
1483     /*
1484      * We cannot use TclGetContinuationTable() here, because that may
1485      * re-initialize the thread-data for calls coming after the finalization.
1486      * We have to access it using the low-level call and then check for
1487      * validity. This function can be called after TclFinalizeThreadData() has
1488      * already killed the thread-global data structures. Performing
1489      * TCL_TSD_INIT will leave us with an un-initialized memory block upon
1490      * which we crash (if we where to access the uninitialized hashtable).
1491      */
1492
1493     {
1494         ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
1495         Tcl_HashEntry *hPtr;
1496
1497         if (tsdPtr->lineCLPtr) {
1498             hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
1499             if (hPtr) {
1500                 ckfree(Tcl_GetHashValue(hPtr));
1501                 Tcl_DeleteHashEntry(hPtr);
1502             }
1503         }
1504     }
1505 }

> If your program was working with some much older version
> of Tcl before the pending delete scheme was put in place,
> that was indeed a long time ago.  All releases of Tcl since
> around 2004 have included that.

It is the test program. It uses the Tcl_ObjType mechanism to define new types directly
from tcl source code. It allows to perform operations in case of automatic destruction
of variables of this type.

TclOO doesn't suit me. TclOO requires an explicit call of a destructor, than does
programming on Tcl in disaster for me.

PS
I consider that TclFreeObj() shall execute at first freeIntRepProc() and only then
to do TclInvalidateStringRep() and TclFreeObjStorage().

/foo

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Tcl-Core mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/tcl-core
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Hidden diversion - "Nested Tcl_Obj deletion management support"

Donald G Porter-2

>>> This code breaks my program.
>>
>> The code you quoted does not appear in any current release
>> of Tcl.
>>
> See below.

Apologies. There are 2 copies of TclFreeObj() and I was looking
at the wrong one.

>> If your program was working with some much older version
>> of Tcl before the pending delete scheme was put in place,
>> that was indeed a long time ago.  All releases of Tcl since
>> around 2004 have included that.

> I consider that TclFreeObj() shall execute at first freeIntRepProc() and only then
> to do TclInvalidateStringRep() and TclFreeObjStorage().

You confirm your code's objection is to a fix made in 2004.

At that time we replaced the recursive scheme of freeing
Tcl values with the current "stackless" scheme.  This change
is a protection against the program-crashing exhaustion of
the C stack that is otherwise possible. See tests obj-32.1,
thread-6.1, and the following line from the changes file:

2004-06-18 (bug fix) prevent stack overflow from long free() chains
(fellows)

We will not be reversing that improvement.  The constraints it makes
on a custom Tcl_FreeInternalRepProc are spelled out in the documentation
of Tcl 8.5 and later.

http://www.tcl.tk/man/tcl/TclLib/ObjectType.htm

--
| Don Porter            Applied and Computational Mathematics Division |
| [hidden email]             Information Technology Laboratory |
| http://math.nist.gov/~DPorter/                                  NIST |
|______________________________________________________________________|

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Tcl-Core mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/tcl-core
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Hidden diversion - "Nested Tcl_Obj deletion management support"

tcl-core mailing list

Вторник, 27 июня 2017, 0:20 +07:00 от Donald G Porter <[hidden email]>:

You confirm your code's objection is to a fix made in 2004.

At that time we replaced the recursive scheme of freeing
Tcl values with the current "stackless" scheme. This change
is a protection against the program-crashing exhaustion of
the C stack that is otherwise possible. See tests obj-32.1,
thread-6.1, and the following line from the changes file:

I have no problems with the first test obj-32.1. If to increase the size of the stack
of threads (try -DTCL_THREAD_STACK_MIN=33554432L), then the second test
thread-6.1 complete without troubles too.

Why you consider that successful execution of the invented test for 100000 nested
TclFreeObj(), is the sufficient base to break an order of a call of destructors?


2004-06-18 (bug fix) prevent stack overflow from long free() chains
(fellows)

We will not be reversing that improvement. The constraints it makes
on a custom Tcl_FreeInternalRepProc are spelled out in the documentation
of Tcl 8.5 and later.

http://www.tcl.tk/man/tcl/TclLib/ObjectType.htm

As I understand, you mean this place in documentation:

"The freeIntRepProc implementation must not access the bytes member of the value,
since Tcl makes its own internal uses of that field during value deletion. The defined
tasks for the freeIntRepProc have no need to consult the bytes member."

:) The documentary error is feature.

"The constraints it makes on a custom Tcl_FreeInternalRepProс ..."
Why you do it? You enter to yourself silly restriction.

/foo
As I understand, you mean this place in documentation

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Tcl-Core mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/tcl-core
Loading...