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: segfaults when using __del__ and weakrefs
Type: Stage:
Components: Interpreter Core Versions: Python 2.5
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: brett.cannon Nosy List: Carl.Friedrich.Bolz, arigo, brett.cannon, georg.brandl, gvanrossum, loewis, mwh, nnorwitz
Priority: critical Keywords:

Created on 2005-12-10 21:20 by Carl.Friedrich.Bolz, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
minimalcrash.py Carl.Friedrich.Bolz, 2005-12-10 21:20 minimal example
weakref_in___del__.diff brett.cannon, 2006-06-29 17:36 clear new weakrefs after calling the finalizer
clear_weakref.diff arigo, 2006-08-12 11:31 patch #2
clear_weakref_w_test.diff brett.cannon, 2006-08-20 04:31 patch #2 w/ extra code comment and test
Messages (12)
msg27025 - (view) Author: Carl Friedrich Bolz-Tereick (Carl.Friedrich.Bolz) * Date: 2005-12-10 21:20
You can segfault Python by creating a weakref to an
object in its __del__ method, storing it somewhere and
then trying to dereference the weakref afterwards. the
attached file shows the described behaviour.
msg27026 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2006-01-09 11:54
Logged In: YES 
user_id=6656

Hmm, I was kind of hoping this report would get more attention.

The problem is obvious if you read typeobject.c around line 660: the weakref 
list is cleared before __del__ is called, so any weakrefs added during the 
execution of __del__ are never informed of the object's death.  One fix for this 
would be to clear the weakref list _after_ calling __del__ but that led to other 
mayhem in ways I haven't boethered to understand <wink> (see SF bug 
#742911).  I guess we could just clear out any weakrefs created in __del__ 
without calling their callbacks.
msg27027 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2006-01-09 11:58
Logged In: YES 
user_id=6656

Hmm, maybe the referenced mayhem is more to do with clearing __dict__ than 
calling __del__.  What breaks if we do things in this order:

1. call __del__
2. clear weakrefs
3. clear __dict__

?
msg27028 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-01-10 19:29
Logged In: YES 
user_id=1188172

Added to outstanding_crashes.py.
msg27029 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2006-06-29 17:36
Logged In: YES 
user_id=357491

So after staring at this crasher it seemed to me to be that
clearing the new weakrefs w/o calling their finalizers after
calling the object's finalizer was the best solution.  I
couldn't think of any other good way to communicate to the
new weakrefs that the object they refer to was no longer
viable memory without doing clear_weakref() work by hand.

Attached is a patch to do this.  Michael, can you have a look?
msg27030 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2006-08-12 11:31
Logged In: YES 
user_id=4771

The clear_weakref(*list) only clears the first
weakref to the object.  You need a while loop
in your patch. (attached proposed fix)

Now we're left with fixing the same bug in
old-style classes (surprize surprize), and
turning the crasher into a test.
msg27031 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2006-08-20 04:31
Logged In: YES 
user_id=357491

After finally figuring out where *list was made NULL (and
adding a comment about it where it occurs), I added a test
to test_weakref.py .  Didn't try to tackle classic classes.
msg27032 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2007-01-17 07:02
Brett, Michael, Armin, can we get this patch checked in for 2.5.1?
msg27033 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2007-01-17 18:38
I have just been waiting on someone to do a final code review on it.  As soon as someone else signs off I will commit it.
msg27034 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2007-01-23 21:26
The first comment has a non-sensical (to me) phrase: "rely on part of theof the object".

Otherwise, it looks fine to me. Please apply, if you can, before 2.5c1.
msg27035 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2007-01-23 23:22
rev. 53533 (for 25-maint) and rev. 53535 (trunk) have the patch with an improved comment.  Py3K should eventually have its crasher file for this test deleted since classic classes will no longer be an issue.
msg61650 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-24 18:59
This got fixed for classic classes in r60057,
and backported to 2.5.2 in 60056.
History
Date User Action Args
2022-04-11 14:56:14adminsetgithub: 42676
2008-01-24 18:59:43gvanrossumsetnosy: + gvanrossum
messages: + msg61650
2005-12-10 21:20:45Carl.Friedrich.Bolzcreate