Path: utzoo!attcan!uunet!mcsun!ukc!pyrltd!tetrauk!rick From: rick@tetrauk.UUCP (Rick Jones) Newsgroups: comp.lang.eiffel Subject: Re: Garbage Collection Problem Message-ID: <742@tetrauk.UUCP> Date: 27 Sep 90 14:59:59 GMT References: <124@alfrat.uucp> Reply-To: rick@tetrauk.UUCP (Rick Jones) Organization: Tetra Ltd., Maidenhead, UK Lines: 70 In article <124@alfrat.uucp> dave@alfrat.uucp (Dave Cullen) writes: >I have been having problems with Segmentation errors being >created when turning on the automatic garbage collection >in Eiffel 2.2, using the option in the SDF. I used garbage >collection in Eiffel 2.1 without any problems, but since >the occurence of the bug seems to be program size dependent >this may have been luck. > >So far I have traced the segmentation error to the function >"set_black" in "_gac.c". It occurs on the second of the following >two lines: > > _rt_3A7 = c_field ((int32)i, _rt_3Ao); > if (!EXPANDED(_rt_3A7)) { > ... There are definitely some bugs in garbage collection in 2.2, in general they seem to result from the extra complications of dealing with expanded and bitfield types (good news - 2.3 beta appears to have sorted a lot of it out). One particular problem which may occur is also due to expanded types, and only indirectly involves the garbage collector, despite the fact that that is where it crashes! This problem is quite specific, and occurs if you call the Create routine on a class which contains an expanded object, and where any of the actual arguments to Create are themselves function calls on other objects. An example I found was creating a FILE object (this contains a DOUBLE, which is an expanded type), where the argument - the file name - was generated by a function call. E.g. f: FILE ; f.Create (obj.getname) ; "getname" is a function call on "obj" which returns a string, and does various things before returning. This may cause a random crash. The reason is that the "f" object is first allocated on the heap, and initialised with all 0's. Then the "f.Create" is called, but of course "obj.getname" has to be called first in order to provide the argument. If the code in "getname" does anything non-trivial, it will trigger a phase of garbage collection, which may result in the collector looking at the newly-allocated null "f" object (with me so far?:) But if "f" contains an expanded type, all-null values is not valid: it should have the header words of the expanded object embedded. The creation of the internal expanded objects is only done within the Create routine, when it calls a hidden class-specific "expand" function. There is thus a window where a new object containing one or more expanded objects is in an invalid state. If the garbage collector gets to look at this object during this window period, it finds what should be an expanded object with no header and just gets lost. The only current solution is to change the source: f: FILE ; n: STRING ; n := obj.getname ; f.Create (n) ; The real overhead of this is virtually zero, just slightly less succinct code. This problem does not appear to be resolved in 2.3 (not beta anyway). I can't tell from your description if this really is the problem, but I suggest checking your source for these sort of things. If it's not this, you may like to know that I also re-worked the 2.2 garbage collector in several places, mainly to see how much faster it would go, but also managed to fix some of the other problems. If you would like a copy, please email me. (caveat: no guarantees or support!) -- Rick Jones The definition of atomic: Tetra Ltd. from the Greek meaning "indivisible" Maidenhead, Berks, UK So what is: rick@tetrauk.uucp an atomic explosion?