On Friday, Apr 18, 2003, at 01:22 Europe/London, Guido van Rossum wrote:
Note that this is quite some time ago :-) I've been reading through some messages that have been ticked for rather too long in my python-dev mail folder...
(Looking at PyObject_GenericGetAttr with that in mind, I wonder if there isn't a possible crash there. In the first MRO lookup, looking for descr's, if a non-data-descr is found, it is kept around but not INCREF'd until later, after the instance-dict is searched. Am I wrong in believing the PyDict_GetItem of the instance dict can call Python code ?
It can, if there's a key whose type has a custom __eq__ or __cmp__. So indeed, if this custom __eq__ is evil enough to delete the corresponding key from the class dict, it could cause descr to point to freed memory. I won't try to construct a case, but it's not impossible. :-(
Indeed not! Here's mine:
class Evil(object): def __hash__(self): return hash('attr') def __eq__(self, other): global foo foo = gc.get_referrers(C.attr) del C.attr return 0
class Descr(object): def __get__(self, ob, type=None): return 1
class C(object): attr = Descr()
c = C() c.__dict__[Evil()] = 0
It's always a bit hard to be sure that stuff like this will actually crash the interpreter, which is what the gimmicks with gc.get_referrers & `foo` are in aid of. This crashes every Python I have lying around on my iBook -- the 2.2[.0] in /usr/bin, heads of release22-maint, release23-maint, the CVS trunk, a random build of 2.2.3c1, Jack's 2.3 build. Etc ;-) I'll check on linux when I get into work.
Fixing this would make the code even hairier though... :-(
Pff, it's not so bad, just a little refcount code jiggling. I'll make a real patch including the above test case soon (once I'm reasonably confident that I'm not leaking references).
And then I find out running test_descr in a loop leaks 166(!) references *anyway* (run the attached blah.py in a debug build, and some print test or other that I don't understand fails when run like this, so I fiddled it)
Should I have been expecting this, or is it time for some ref-leak hunting? Actually, the process seems to grow -- slowly -- when you loop, so it's probably a real problem. I gather it's best to ask about this sort of thing when Tim is off sick from work :-)