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: infinite recursion in PyErr_WriteUnraisable
Type: crash Stage: resolved
Components: Interpreter Core Versions: Python 2.6
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: BreamoreBoy, amaury.forgeotdarc, ldeller, loewis, pitrou, serhiy.storchaka, vstinner
Priority: normal Keywords: patch

Created on 2009-02-12 04:28 by ldeller, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
recursebug.py ldeller, 2009-02-12 04:28 small example which crashes the interpreter
recursioncheck.patch amaury.forgeotdarc, 2009-03-09 12:31
Messages (12)
msg81721 - (view) Author: lplatypus (ldeller) * Date: 2009-02-12 04:28
Here is an example of pure Python code which can cause the interpreter
to crash.

I can reproduce the problem in 2.6.0 and 2.6.1 but not in 2.5.2.

The __getattr__ function in this example is interesting in that it
involves infinite recursion, but then the RuntimeError("maximum
recursion depth exceeded") actually causes it to behave correctly.  This
is due to the behaviour of hasattr which suppresses any exception caught
when checking for attributes.

Added to the mix we have sys.stderr replaced by an instance with a write
method.  The key ingredient here is that getattr(sys.stderr, "write")
invokes Python code.  Near the interpreter's recursion limit this python
code can fail.  This causes infinite recursion in C.

Here is a snippet of the call stack from gdb showing the recursion cycle
(using 2.6.0 source code):

#9  0x00000000004a442c in PyErr_WriteUnraisable (obj=0x64ae40)
    at Python/errors.c:606
#10 0x00000000004a48f5 in PyErr_GivenExceptionMatches (err=0x64ae40,
    exc=0x64ae40) at Python/errors.c:115
#11 0x0000000000466056 in slot_tp_getattr_hook (self=0x70a910,
    name=0x2b4a94d47e70) at Objects/typeobject.c:5426
#12 0x0000000000449f4d in PyObject_GetAttrString (v=0x70a910,
    name=0x7fff155e2fe0 <Address 0x7fff155e2fe0 out of bounds>)
    at Objects/object.c:1176
#13 0x000000000042e316 in PyFile_WriteObject (v=0xd02d88, f=0x70a910,
flags=1)
    at Objects/fileobject.c:2362
#14 0x000000000042e5c5 in PyFile_WriteString (s=0x51704a "Exception ",
    f=0x70a910) at Objects/fileobject.c:2422
#15 0x00000000004a442c in PyErr_WriteUnraisable (obj=0x64ae40)
    at Python/errors.c:606
msg81723 - (view) Author: lplatypus (ldeller) * Date: 2009-02-12 05:09
I believe that this problem was introduced in subversion revision 65319.
msg81724 - (view) Author: lplatypus (ldeller) * Date: 2009-02-12 05:11
sorry I meant revision 65320
msg83354 - (view) Author: lplatypus (ldeller) * Date: 2009-03-09 03:56
Hi amaury, I am copying you into this issue because I think it was
introduced in your revision 65320 when you added a call to
PyErr_WriteUnraisable from PyErr_GivenExceptionMatches in Python/errors.c.
Any thoughts on on this issue or how to fix it would be very welcome.
msg83375 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-03-09 12:31
python 3.0 does not crash. And it has better code for infinite recursion
(r55850, r66186)
I suggest to backport the py3k code, patch attached.

Martin, your comments are welcome. Are there compatibility issues?
msg83481 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-03-11 23:05
Amaury, there is a funny bug in the 3.0 implementation with very low
recursion limits (#5392).
msg83515 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-03-13 12:37
yes, let's add this change to the backport.
msg99128 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-02-09 17:06
As already mentioned, the backport patch isn't up to date.
msg111841 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-07-28 20:41
Could the experts who have previously commented please advise as to whether this issue should be open, closed or whatever.
msg125280 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-01-04 02:02
Works fine under 2.7-3.2. Not sure this is worth fixing in 2.6.
msg173063 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2012-10-16 17:33
On 2.7 prints two 42, on 3.x fails (RuntimeError: maximum recursion depth exceeded in comparison) on first call. 2.6 out of date for non-security fix.
msg173082 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-10-16 19:38
Ok, so I would say this whole issue is out of date now, since maintained branches don't show the issue.
History
Date User Action Args
2022-04-11 14:56:45adminsetgithub: 49473
2012-10-16 19:38:59pitrousetstatus: open -> closed
resolution: out of date
messages: + msg173082

stage: patch review -> resolved
2012-10-16 17:33:47serhiy.storchakasetstatus: pending -> open
nosy: + serhiy.storchaka
messages: + msg173063

2011-01-04 02:02:42pitrousetstatus: open -> pending
nosy: loewis, amaury.forgeotdarc, pitrou, vstinner, ldeller, BreamoreBoy
messages: + msg125280
2010-07-28 20:41:42BreamoreBoysetnosy: + BreamoreBoy
messages: + msg111841
2010-02-09 17:06:02pitrousetmessages: + msg99128
2010-02-09 16:43:57brian.curtinsetpriority: normal
stage: patch review
2009-03-13 12:37:07amaury.forgeotdarcsetmessages: + msg83515
2009-03-11 23:05:26pitrousetnosy: + pitrou
messages: + msg83481
2009-03-09 12:31:22amaury.forgeotdarcsetfiles: + recursioncheck.patch

nosy: + loewis
messages: + msg83375

keywords: + patch
2009-03-09 03:56:10ldellersetnosy: + amaury.forgeotdarc
messages: + msg83354
2009-02-12 11:36:56vstinnersetnosy: + vstinner
2009-02-12 05:11:24ldellersetmessages: + msg81724
2009-02-12 05:09:18ldellersetmessages: + msg81723
2009-02-12 04:28:34ldellercreate