Re: [Gc] Infinite Loop in GC_clear_fl_marks
Bruce Hoult <[email protected]>
| Newsgroups | gmane.comp.programming.garbage-collection.boehmgc |
|---|---|
| Message-ID | <CAMU+Ekx=nzaw8LMfGqAkLLf4_yfNvSvj_RKfezYOSVxeSBTTKQ@mail.gmail.com> |
I just wrote an explanation of the same symptom (looping in GC_clear_fl_marks()) elsewhere. Perhaps it can help others here too. Simply put, it is not a bug in the GC and can only happen from a user code memory-stomper or buggy use of GC_free(). As a first approximation, never use GC_free(). If you have a problem that you think may be a bug in the GC then disable all your uses of GC_free() and see if the problem persists. Preferably, don't write memory-stompers either. Use a safe language with bounds checks and no pointer arithmetic. ---------------- The GC keeps a list of free objects for each size object. When a new object is wanted the first object in the appropriate free list is unlinked and returned. If the free list is empty then an unused memory block (normally a VM page on the CPU being being used, i.e. probably 4 KB) is found or created, subdivided into equal-sized objects, and linked together as the new free list. In normal use a free list will always consist of a simple linear list of objects from a single VM page, ordered by ascending memory address. This code is extremely simple, robust, and well tested. It does not need any cycle detection slowing it down. Therefore, cycles can only be created by unsafe code memory-stomping the data structure. If you have a memory stomper then absolutely anything could happen and a loop in GC_clear_fl_marks() is probably one of the more benign cases. The exception to this is GC_free(). GC_free() adds the object to the start of the free list. When you next allocate an object of that size (of any class) you WILL get back the object most recently GC_free()'d. GC_free() is never necessary. It is purely a performance hack. If you use it you turn your safe language (e.g. Dylan) into an unsafe language no better than C. If you call GC_free() on an object that you still have another reference to then very bad things can happen. You will probably very quickly end up with two objects in your program that share the same memory. They might be of different classes. Assignments to fields of one object (e.g. the initializer of the new object) will change fields in the other object. All kinds of invariants that user code or your safe-language compiler rely on can be violated. A second call to GC_free() causing a loop in the free list is once again probably one of the most benign things that can happen. The program does not continue. You don't get wrong results later. The program stopping with an error message would be slightly more helpful, but is it worth slowing down GC_clear_fl_marks() for normal code, just to compensate for incorrect use of an inherently unsafe performance hack, when the other likely results from calling GC_free() on an object you're still using are so much worse? I don't think so. If there should be a check for free list loops anywhere, it should be in the only non-stomper place that can create them: GC_free() itself. Stepping through the entire free list checking that the object you're freeing isn't already on the free list (or checking for a preexisting loop) is almost certainly more expensive than simply not using GC_free() and allowing the object to be GC'd in the normal way. Don't use GC_free() unless you are really really really sure that you are using it properly. And even then, you are probably better off using your own explicit free list for objects of that class. You'll still get incorrect results if you make a mistake, but they'll be a lot less wrong :) On Tue, Mar 25, 2014 at 7:33 AM, Alexander Herz <[email protected]>wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Hi, > > I'm running bdwgc 7.3 on SUSE Linux Enterprise Server 10 sp3 in an MPI > setting. One of our programs consistently (but not allways after the > same number of iterations) enters an infinite loop with the following > call stack: > > GC_malloc_atomic > GC_generic_malloc_many > GC_generic_malloc_inner > GC_allocobj > GC_collect_or_expand > GC_try_to_collect_inner > GC_finish_collection > GC_clear_fl_marks <———— > > The for(;;) loop never terminates because q never equals null. Also > the value returned by GC_bytes_found negativ becomes negative. > > Any ideas what could be going wrong here or how to get more information? > > Thx, > Alex > > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.11 (GNU/Linux) > Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ > > iQEcBAEBAgAGBQJTMHpdAAoJEGSriSINjxXwlioIAJGX+u2v69PKhdAedJyDK2eT > RP45RUbKhWuQSpmsIWecWVCjanlPjoyY2w2gl9bDct/3A1d6PChx7mmmn1cOB9gt > 0pbw9VjT5a993i3TwjxGB7G6N8NLieYel7DaB5JXgWQGOh3oDk5NhUBVGmU73vzJ > ffCOIssWaMKWW2n2CJXkkT5VoYphx7wLjIbNXdjFLbAQYwSPcaCueBkNsYu8ImQb > zNggBdO55jre/BXEIDIFduEZW1p2BfSScUEA8L1zEMLlTYpxz+xhxOahriyU2sit > 71VsQNBu8RwVuoBb8ZPmUh1OjWOHjHwgdgQ+9h06BYKzcAlJGZTaQBz55oiQJyE= > =ZBxz > -----END PGP SIGNATURE----- > _______________________________________________ > bdwgc mailing list > [email protected] > https://lists.opendylan.org/mailman/listinfo/bdwgc > > -- > This message has been scanned for viruses and > dangerous content by MailScanner, and is > believed to be clean. > > _______________________________________________ bdwgc mailing list [email protected] https://lists.opendylan.org/mailman/listinfo/bdwgc