Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python SEGFAULT on tuple.__repr__ and str() #44763

Closed
ludvigericson mannequin opened this issue Mar 22, 2007 · 14 comments
Closed

Python SEGFAULT on tuple.__repr__ and str() #44763

ludvigericson mannequin opened this issue Mar 22, 2007 · 14 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@ludvigericson
Copy link
Mannequin

ludvigericson mannequin commented Mar 22, 2007

BPO 1686386
Nosy @brettcannon, @birkenfeld
Files
  • 1686386.diff
  • infinite_rec_fix.diff
  • 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 = 'https://github.com/brettcannon'
    closed_at = <Date 2007-09-30.19:46:02.886>
    created_at = <Date 2007-03-22.22:00:13.000>
    labels = ['interpreter-core', 'type-crash']
    title = 'Python SEGFAULT on tuple.__repr__ and str()'
    updated_at = <Date 2007-09-30.20:37:42.555>
    user = 'https://bugs.python.org/ludvigericson'

    bugs.python.org fields:

    activity = <Date 2007-09-30.20:37:42.555>
    actor = 'brett.cannon'
    assignee = 'brett.cannon'
    closed = True
    closed_date = <Date 2007-09-30.19:46:02.886>
    closer = 'brett.cannon'
    components = ['Interpreter Core']
    creation = <Date 2007-03-22.22:00:13.000>
    creator = 'ludvig.ericson'
    dependencies = []
    files = ['8358', '8423']
    hgrepos = []
    issue_num = 1686386
    keywords = ['patch']
    message_count = 14.0
    messages = ['31624', '31625', '31626', '55468', '55484', '55685', '55690', '55864', '55871', '55874', '55879', '56057', '56201', '56202']
    nosy_count = 4.0
    nosy_names = ['brett.cannon', 'georg.brandl', 'therve', 'ludvig.ericson']
    pr_nums = []
    priority = 'high'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'crash'
    url = 'https://bugs.python.org/issue1686386'
    versions = ['Python 2.6', 'Python 2.5']

    @ludvigericson
    Copy link
    Mannequin Author

    ludvigericson mannequin commented Mar 22, 2007

    When one uses a class that has derived BaseException in one way or another and uses an invalid super() and calls a function upon that object, Python dies with SIGSEGV.

    Reproduce code:
    >>> class X(BaseException):
    ...     def __init__(self):
    ...             super(X, self).__init__(self)
    ... 
    >>> X()
    Segmentation fault

    I could reproduce this on two different Python 2.5 installations.

    This is as much as I could get from gdb:
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread -1211660624 (LWP 30234)]
    0xb7ea601c in _PyObject_GC_Malloc () from /usr/lib/libpython2.5.so.1.0
    (gdb) bt
    #0 0xb7ea601c in _PyObject_GC_Malloc () from /usr/lib/libpython2.5.so.1.0
    #1 0xb7ea613b in _PyObject_GC_NewVar () from /usr/lib/libpython2.5.so.1.0
    #2 0xb7e4abe4 in PyTuple_New () from /usr/lib/libpython2.5.so.1.0
    #3 0xb7e4b48d in ?? () from /usr/lib/libpython2.5.so.1.0
    #4 0x00000001 in ?? ()
    #5 0x00000000 in ?? ()

    @ludvigericson ludvigericson mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Mar 22, 2007
    @ludvigericson
    Copy link
    Mannequin Author

    ludvigericson mannequin commented Mar 22, 2007

    It might be added that this works (throws an exception) in python 2.4 (though, BaseException does not exist there):
    TypeError: super() argument 1 must be type, not classobj

    @birkenfeld
    Copy link
    Member

    This is not new in 2.5. That is does not work with super() in 2.4 is because in 2.4 exceptions are old-style classes.
    Look at this:
    >>> class X(Exception):
    ...  def __init__(self):
    ...   Exception.__init__(self, self)
    ...
    >>> x=X()
    >>> str(x)
    [1]    4396 segmentation fault  python2.4

    The problem is that str(x) calls str(x) etc.

    @therve
    Copy link
    Mannequin

    therve mannequin commented Aug 30, 2007

    Here is a patch correcting the problem, with tests. It doesn't have much
    to do with exception, it's mainly a problem with PyObject_Str and
    PyObject_Repr, that I corrected with Py_EnterRecursiveCall calls.

    Maybe the bug should be reclassified, at least the title changed.

    @therve therve mannequin added type-crash A hard crash of the interpreter, possibly with a core dump labels Aug 30, 2007
    @ludvigericson
    Copy link
    Mannequin Author

    ludvigericson mannequin commented Aug 30, 2007

    Minor note: The patch mixes tabs and spaces. AFAIK, PEP-7 says to use
    four spaces when making new code, and follow suite in legacy, or convert it.

    @therve
    Copy link
    Mannequin

    therve mannequin commented Sep 6, 2007

    object.c is already inconsistent about tabs and space :). It may be
    better to fix it in the commit, not to clutter the patch. But I can
    provide a new patch if necessary.

    @ludvigericson
    Copy link
    Mannequin Author

    ludvigericson mannequin commented Sep 6, 2007

    Hm, may be so.

    Feel free to change title/severity if you'd like to.

    @birkenfeld
    Copy link
    Member

    Brett, you recently fixed an infinite recursion crasher, right?

    @brettcannon
    Copy link
    Member

    So the first example (in msg31624) crashes because of infinite recursion
    with the repr of exceptions::

    bpo-7771 0x00065178 in BaseException_repr (self=0x5dc6b8) at
    Objects/exceptions.c:128
    bpo-7772 0x0001d90c in PyObject_Repr (v=0x5dc6b8) at Objects/object.c:362
    bpo-7773 0x0008c180 in tuplerepr (v=0x5dad58) at Objects/tupleobject.c:221

    The second one in msg31626 dies because of the str of exceptions::

    bpo-3839 0x0001dd88 in PyObject_Str (v=0x5dc6b8) at Objects/object.c:427
    bpo-3840 0x00065120 in BaseException_str (self=0x5dc6b8) at
    Objects/exceptions.c:110
    bpo-3841 0x0001dc0c in _PyObject_Str (v=0x5dc6b8) at Objects/object.c:407

    Both fail because BaseException uses the str/repr of its arguments to
    construct what string to return. When it's itself it just goes on
    forever trying to get the next object's representation.

    The repr issue might be fixed by looking at how lists catch loops in
    themselves (don't remember the exact C function). Either way it is not
    really str/repr that is causing the issue but exceptions for not
    worrying about possible recursion thanks to using the str/repr of
    contained objects.

    @brettcannon
    Copy link
    Member

    OK, so I have attached a possible patch. I found out that
    tuple.__repr__ didn't do anything to prevent infinite recursion since
    you can't pull it off from Python code. But obviously C code is another
    matter. =)

    Same goes for object.__str__; it didn't think about a type's tp_str
    doing something that could lead to an infinite recursion.

    Assigning back to Georg to make sure I am not doing something stupid nor
    that the approach is to broad by changing _PyObject_Str() and
    tuple.__repr__ instead of BaseException itself.

    I have not written tests yet as they are rather difficult to do for what
    the C code is doing without relying specifically on how exceptions do
    their __repr__/str.

    @brettcannon brettcannon changed the title Python SEGFAULT on invalid superclass access Python SEGFAULT on tuple.__repr__ and str() Sep 12, 2007
    @brettcannon brettcannon changed the title Python SEGFAULT on invalid superclass access Python SEGFAULT on tuple.__repr__ and str() Sep 12, 2007
    @therve
    Copy link
    Mannequin

    therve mannequin commented Sep 13, 2007

    I think it could be solved both the same way: if tuple repr is wrong,
    there are probably some other repr code that is wrong too, so fixing
    PyObject_Repr is safer.

    @birkenfeld
    Copy link
    Member

    I don't have a specific opinion on this; the usage of
    Py_EnterRecursiveCall/Py_ReprEnter certainly looks correct.

    @birkenfeld birkenfeld assigned brettcannon and unassigned birkenfeld Sep 20, 2007
    @brettcannon
    Copy link
    Member

    Applied in r58288. If I did something stupid or people don't want the
    overhead they can yell at the commit. =)

    @brettcannon
    Copy link
    Member

    And fixed in r58289.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants