Skip to content

recursion core dumps #41493

Closed
Closed

Description

@jengeldk
mannequin
BPO 1110055
Nosy @tim-one, @josiahcarlson

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2005-01-29.20:20:29.000>
created_at = <Date 2005-01-26.17:18:09.000>
labels = ['interpreter-core', 'invalid']
title = 'recursion core dumps'
updated_at = <Date 2005-01-29.20:20:29.000>
user = 'https://bugs.python.org/jengeldk'

bugs.python.org fields:

activity = <Date 2005-01-29.20:20:29.000>
actor = 'tim.peters'
assignee = 'none'
closed = True
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2005-01-26.17:18:09.000>
creator = 'jengeldk'
dependencies = []
files = []
hgrepos = []
issue_num = 1110055
keywords = []
message_count = 4.0
messages = ['24058', '24059', '24060', '24061']
nosy_count = 4.0
nosy_names = ['tim.peters', 'josiahcarlson', 'logistix', 'jengeldk']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue1110055'
versions = []

Activity

  1. jengeldk commented on Jan 26, 2005

    jengeldkmannequin
    MannequinAuthor

    when running recursive function you get a coredump with
    deep recursion.
    eg

    from sys import *
    n = 30000
    setrecursionlimit(n+1)
    
    def fact(n):
       if n==1:
          return 1
       return fact(n-1)*n
    
    fact(n)

    This is seen on linux i686 with both python2.3 and
    python2.4, the recursion depth which triggers the core
    dump is 26211 with python2.4 and 29123 with python2.3
    with a machine having 2076860 kB of memory, on machines
    with less memory smaller numbers are seen.

    this is what gdb tells me:
    jacob@pauling:/scratch/jacob$ gdb /usr/bin/python2.4 core
    GNU gdb 6.3-debian
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public
    License, and you are
    welcome to change it and/or distribute copies of it
    under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show
    warranty" for details.
    This GDB was configured as "i386-linux"...(no debugging
    symbols found)
    Using host libthread_db library
    "/lib/tls/libthread_db.so.1".

    (no debugging symbols found)
    Core was generated by `python2.4 /home/user_4/jacob/rr
    30000'.
    Program terminated with signal 11, Segmentation fault.

    warning: current_sos: Can't read pathname for load map:
    Input/output error

    Reading symbols from /lib/tls/libpthread.so.0...(no
    debugging symbols found)...done.
    Loaded symbols for /lib/tls/libpthread.so.0
    Reading symbols from /lib/tls/libdl.so.2...(no
    debugging symbols found)...done.
    Loaded symbols for /lib/tls/libdl.so.2
    Reading symbols from /lib/tls/libutil.so.1...(no
    debugging symbols found)...done.
    Loaded symbols for /lib/tls/libutil.so.1
    Reading symbols from /lib/tls/libm.so.6...
    (no debugging symbols found)...done.
    Loaded symbols for /lib/tls/libm.so.6
    Reading symbols from /lib/tls/libc.so.6...(no debugging
    symbols found)...done.
    Loaded symbols for /lib/tls/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...(no debugging
    symbols found)...done.
    Loaded symbols for /lib/ld-linux.so.2

    #0 0x400c94bf in mallopt () from /lib/tls/libc.so.6

  2. logistix commented on Jan 29, 2005

    logistixmannequin
    Mannequin

    Logged In: YES
    user_id=699438

    This looks like a stack overflow. There's not much python
    can do when the stack runs out of memory, which is why the
    default recursion limit is set to 1000.

    Also, at least in the reproducable, the number you are building
    is going to consume excessive amounts of memory.

    I ran this test (to avoid creating a giant long number) and still
    got the segfault.

    from sys import *
    n = 30000
    setrecursionlimit(n+1)
    
    def nofact(n):
        if n==1: 
            return 1
        return nofact(n-1)
    
    nofact(n)
  3. josiahcarlson commented on Jan 29, 2005

    josiahcarlsonmannequin
    Mannequin

    Logged In: YES
    user_id=341410

    The fact that an error occurs is not surprising. Python is
    limited by the C stack size, which from what I understand is
    well below 2GB.

    The fact that it gets to nearly 30k levels of recursion for
    you is amazing to me, the most used platform (Windows) can
    only ever get to around 5500 levels before they get
    "MemoryError: stack overflow" exceptions.

    I believe that the reason you are getting a segfault on
    linux is the way the linux malloc() and free() work.
    Specifically, malloc() on linux will give you a pointer to
    memory, regardless of whether it is available. If your
    program has used up all of its stack space, and you need
    more, the pointer will be invalid. If Python happens to
    call a free() before you actually access the invalid
    pointer, everything will work. If Python doesn't call
    free() before you access the invalid pointer, you get a
    segfault.

    Unfortunately, there is no way that Python (or any other
    program on linux) can know that the pointer it has gotten
    from malloc() is invalid.

    Furthermore, as per the docs here:
    http://docs.python.org/lib/module-sys.html

    "
    setrecursionlimit(limit)
    Set the maximum depth of the Python interpreter stack to
    limit. This limit prevents infinite recursion from causing
    an overflow of the C stack and crashing Python.

    The highest possible limit is platform-dependent. A user may
    need to set the limit higher when she has a program that
    requires deep recursion and a platform that supports a
    higher limit. This should be done with care, because a
    too-high limit can lead to a crash."

    I would suggest that this bug be closed as "3rd party, will
    not fix", and suggest the OP read the documentation.

  4. tim-one commented on Jan 29, 2005

    @tim-one
    Member

    Logged In: YES
    user_id=31435

    The docs for setrecursionlimit() are indeed already quite clear
    that you boost its default value at your own risk. So this
    isn't a bug, it's a documented limitation.

  5. transferred this issue fromon Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions