python-greenlet/greenlet — comment on commit 5fd593c29b860512af0143315096f7b797a0c0fa
File:  line 0
By snaury:

Happy New Year and thank you! :)

Unfortunately, just like I said on GTalk about guessing compiler's stack layout it's unsafe, and doesn't really work e.g. on OS X. The problem is that Python's gc stack heads are not an array, they are separate variables, so compiler doesn't have to place them on stack one after another (or maintain order), compiler doesn't have to even place them nearby or to adhere to any array alignment rules. For example, on OS X 10.7 I need PyGC_Head *flist = list - 1 to get to the finalizers list, but even then it's incomplete, because for finalizers list you'd need two sentinels (one at the end and one at the start). Unreachable list doesn't need the start sentinel because greenlet itself acts as one. :)

But even if you manage to guess compiler's stack layout (and bear in mind that Python might be compiled with different compiler than the extension itself), and place sentinels perfectly, there's still a situation where greenlet's tp_clear won't be called at all, yet greenlet will be garbage collected with a switch causing stack corruption and crashes. See https://github.com/snaury/greenlet/commit/e892bfbae13e7fe92e48cbd0b648d06901faeb94 I just commited (luckily this situation cannot happen when only dead/unstarted greenlets are garbage collectable, otherwise greenlet won't be safe at all).

This basically proves that full gc cannot be made safe. Besides, it's not really full, too many limitations, main being greenlet subclasses that define a run method cannot be garbage collected, which severely limits real-world applications (e.g. gevent and eventlet define their own greenlet subclasses with a run method, thus not garbage collectable while live). So I'd scrap the idea of "full gc" completely. :(