This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Bug in type's GC handling causes segfaults
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: tim.peters Nosy List: dcjim, tim.peters
Priority: release blocker Keywords:

Created on 2003-11-10 21:32 by dcjim, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
typepatch.txt dcjim, 2003-11-10 21:32 Fix patch
Messages (4)
msg18962 - (view) Author: Jim Fulton (dcjim) (Python triager) Date: 2003-11-10 21:32
type has a bug in it's GC "clear" function, type_clear.

It sets tp->mro to NULL, but other code (especially
PyObject_GenericGetAttr) assumes that tp_mro cannot be
null.

A class participating in a cycle may have clear called
while there are still instances around.  If someone
tries to do a getattr on such an instance, python will
crach with a segfault or with an assertion error.

A simple fix is for clear to set tp_mro to an empty tuple, 
which breaks the cycle without breaking the invariant.  
A patch is attached.

I encountered this in Zope 3 after adding a new
interface implementation that made heavy use of
weakrefs. Often Zope 3 would segfault when exiting. 
The patch fixes this.

Unfortunately, I was not able, in the time available,
to come up with a simpler test case. :)

msg18963 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2003-11-17 03:23
Logged In: YES 
user_id=31435

Assigned to me.  Please see patch 843455, which should 
repair the problem, but via a different route:  the underlying 
problem is that gc never expected that arbitrary Python code 
could run while gc is running.  A lot of bad things can go 
wrong.  But weakref callbacks have enough nice exploitable 
properties that I think it's possible for gc to run them if it's 
made acutely aware of them, and the patch does that, 
ensuring that a callback (or even later Python code, if a 
callback resurrects dead objects in cycles) never sees an 
object on which tp_clear() has been run.  In particular, then, 
in your callback the __mro__ won't be NULL -- or anything 
else surprising (it will be what you expect the class's __mro__ 
to be).
msg18964 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2003-11-20 21:20
Logged In: YES 
user_id=31435

Boosted priority.
msg18965 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2003-11-20 21:24
Logged In: YES 
user_id=31435

Fixed, via

Include/weakrefobject.h; new revision: 1.4
Lib/test/test_weakref.py; new revision: 1.32
Misc/NEWS; new revision: 1.896
Modules/gc_weakref.txt:  new file
Modules/gcmodule.c; new revision: 2.74
Objects/weakrefobject.c; new revision: 1.14

I'll backport those to 2.3 maint too.
History
Date User Action Args
2022-04-11 14:56:01adminsetgithub: 39532
2003-11-10 21:32:44dcjimcreate