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.

Title: infinite __str__ recursion in thread causes seg fault
Type: Stage:
Components: Interpreter Core Versions: Python 2.3
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: aimacintyre, brett.cannon, georg.brandl, josiahcarlson, loewis, nnorwitz, sf-robot, stefan_gregory
Priority: normal Keywords:

Created on 2003-07-31 08:37 by stefan_gregory, last changed 2022-04-10 16:10 by admin. This issue is now closed.

Messages (9)
msg17508 - (view) Author: Stefan Gregory (stefan_gregory) Date: 2003-07-31 08:37
The following code reliably produces a segmentation
fault under Solaris8 in Python2.3, Python2.2,
Python2.1.3 and Python1.5. It produces a Bus Error when
run on Python2.2 under OSX. Clearly it should produce a
Python RuntimeError.

import thread, time

class Frog:

    def __str__(self):
        return str(self)

f = Frog()

This problem manifests in scenarios such as when you
have 2 publishing objects (such as HTMLgen objects) A
and B and you put A inside B and B inside A and each
objects __str__ method calls its childrens __str__
methods and voila! (I hope this might be the reason my
Zope server has been intermitently crashing for the
past year or so though I have not found any recursive
structures yet.)

With Python2.3 gdb reports:

vgetargskeywords (args=0x1bdaf0, keywords=0x0,
format=0xd2579 "0:str", kwlist=0xf7b4c,
p_va=0xfed0C02c) at Python/getargs.c:1167

Though with Python2.1 it dies at line 330 in getargs.c.

msg17509 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2003-08-05 19:19
Logged In: YES 

If you run ``str(Frog())`` instead of a bunch of threads you do get 
a RuntimeError.  Looks like this bus error has something to do 
with thread.start_new_thread and not 'str'.  It might be that since 
it runs using pthreads it does not have the built-in recursion limit 
check that the Python interpreter has.  Anyone with more 
experience with the 'thread' module have any ideas?
msg17510 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2003-08-05 19:22
Logged In: YES 

Forgot to mention that Modules/threadmodule.c has 
thread_PyThread_start_new_thread which uses Python/
thread_*.h's PyThread_start_new_thread for executing threads;  
the '*' is replaced with the threading library used on your 
platform.  OS X should use thread_pthread.h (I think).
msg17511 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-07-30 11:16
Logged In: YES 

Under 2.5, I get a runtime error now, so this might be fixed.
msg17512 - (view) Author: SourceForge Robot (sf-robot) Date: 2006-08-14 02:20
Logged In: YES 

This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 14 days (the time period specified by
the administrator of this Tracker).
msg17513 - (view) Author: Josiah Carlson (josiahcarlson) * (Python triager) Date: 2006-08-16 07:42
Logged In: YES 

>>> import sys
>>> sys.setrecursionlimit(10000)
>>> class foo:
...     def __str__(self):
...             return str(self)
>>> import threading
>>> threading.Thread(target=foo().__str__).start()

Kills 2.3, 2.4, and 2.5 on Windows, and 2.3 and 2.4 on linux
(I can't test 2.5 on linux).  Running in the main thread on
Windows doesn't seem to be a big deal:

>>> import sys
>>> sys.setrecursionlimit(10000)
>>> class foo:
...     def __str__(self):
...             return str(self)
>>> try:
...     str(foo())
... except Exception, why:
...     print why
Stack overflow

Note that the above crashes 2.3 and 2.4 on Linux.

This is still a bug, at least in maintenance on 2.4. 
Suggested reopen.
msg17514 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-09-10 00:03
Logged In: YES 

I fail to see the problem. You have to change the recursion
limit; if you do, you risk a crash, as the documentation says:
"This should be done with care, because a too-high limit can
lead to a crash."

With an unmodified recursionlimit in 2.4.3 on Windows, I get
the expected RuntimeError. If it causes a crash on some
system, it just means that the default recursion limit is
too high for that platform (however, we don't seem to have a
confirmation that the default recursion limit is too large
for this application on any platform for Python 2.4 or 2.5).

It is quite common that the system provides the main thread
with a larger stack space than any additional thread, so it
is not surprising that the stack overflow is detected on
some system when the code is run in the main thread, yet
crashes in an additional thread. The default recursion limit
should be the conservative minimum of what the system
minimally guarantees for any thread.

It seems that the original problem has been fixed (although
nobody apparently has tested Python 2.4 or 2.5 on Solaris8);
I suggest to close this as fixed again.
msg17515 - (view) Author: Andrew I MacIntyre (aimacintyre) * (Python triager) Date: 2006-09-10 07:14
Logged In: YES 

As of 2.5, the stack size for a thread can be set before the
thread is created.

Windows and Linux seem to default to generous thread stack
sizes (1MB or more), other platforms are parsimonious by
comparison (eg FreeBSD at 64kB).
msg17516 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-11-21 09:08
I agree with Martin, closing.
Date User Action Args
2022-04-10 16:10:23adminsetgithub: 38982
2003-07-31 08:37:02stefan_gregorycreate