| 
     
      
      
      From: SourceForge.net <no...@so...> - 2004-01-28 16:02:31
      
     
   | 
Bugs item #886231, was opened at 2004-01-28 06:37 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=886231&group_id=10894 Category: 40. Memory Allocation Group: None Status: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Jeffrey Hobbs (hobbs) Summary: Tcl interpreter does not lazy-free objects. Initial Comment: testing a references support for Tcl I'm developing (that will be the subject of another comunication), I discovered a bug that is very common in languages implementations using reference counts. The problem is that when a reference of an object drops to zero, the Tcl_DecrRefCount() calls Tcl_FreeObj() in order to free the object internal representation, string, and storage allocation. If that object is able to take references to other objects, before to free the object, all the referenced objects gets RefDecremented(), and this can result in a new (recursive) invocation of Tcl_FreeObj(). That's how it should be in theory, but with deeply nested data structures, for example lists containing lists containing lists (...) the result is a deep recursion of Tcl_FreeObj(), and once the C stack is terminated, a segmentation fault. The following code will crash Tcl on many operating systems and many archs: set x foobar time {lset x 0 [list $x 2]} 20000 set x {} If this is not able to crash your box, try with a value a bit bigger than 20000. Another way to crash Tcl is to substitute the "set x {}" final command with "string length $x". Because the list -> string conversion also is a recursive call. Of course the 'free' problem is much severe than the string conversion one, but fortunatelly the fix is general and quite simple. To fix this problem Tcl should "lazy free" objects. Instead to really free the object, Tcl_FreeObj() should just put the object's pointer in a ToFree list, then free that list only when Tcl_FreeObj() is not called recursively (an alternative is to call a Tcl_FreeCycle() when there is some allocation action, and on low memory). I did a simple implementation for Tcl HEAD (attached to this email). Seems to work well but should be modified to support threads and the Tcl coding style. Regards, Salvatore Sanfilippo ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=110894&aid=886231&group_id=10894  |