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.

Author Dennis Sweeney
Recipients Dennis Sweeney, pablogsal, xtreak, xxm
Date 2021-11-17.04:37:46
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1637123866.89.0.393774226817.issue45826@roundup.psfhosted.org>
In-reply-to
Content
I got a segfault in a similar location:

static PyObject *
offer_suggestions_for_name_error(PyNameErrorObject *exc)
{
    PyObject *name = exc->name; // borrowed reference
    PyTracebackObject *traceback = (PyTracebackObject *) exc->traceback; // borrowed reference
    // Abort if we don't have a variable name or we have an invalid one
    // or if we don't have a traceback to work with
    if (name == NULL || traceback == NULL || !PyUnicode_CheckExact(name)) {
        return NULL;
    }

    // Move to the traceback of the exception
    while (traceback->tb_next != NULL) {  <<<<<<<<<<<<<<< segfault: traceback is junk (but not null) pointer
        traceback = traceback->tb_next;
    }
...


Adding ```assert(Py_TYPE(exc) == PyExc_NameError);``` fails, so somehow something is getting cast to ```PyNameErrorObject *``` when it shouldn't be.

Here is some debugging code I used that also causes the crash:


----------------------------------------------
from unittest import TestCase
from unittest.case import _AssertRaisesContext
import sys
import traceback

manager = _AssertRaisesContext(Exception, TestCase(), 'aaa')

# inline this:
# with manager:
#      aab

try:
    aab
except:

    # inline __exit__
    exc_type, exc_value, tb = sys.exc_info()
    traceback.clear_frames(tb)
    manager.exception = exc_value.with_traceback(None)
    output = '"{}" does not match "{}"'.format(
                     manager.expected_regex.pattern, str(exc_value))

    # inline manager._raiseFailure(output)
    msg = manager.test_case._formatMessage(manager.msg, output)
    print("A:", f"{msg=!r}")
    e = manager.test_case.failureException(msg)
    print("B:", f"{e=!r}")
    raise e

# Output:
# A: msg='"aaa" does not match "name \'aab\' is not defined"'
# B: e=AssertionError('"aaa" does not match "name \'aab\' is not defined"')
-----------------------------------------------
History
Date User Action Args
2021-11-17 04:37:46Dennis Sweeneysetrecipients: + Dennis Sweeney, pablogsal, xtreak, xxm
2021-11-17 04:37:46Dennis Sweeneysetmessageid: <1637123866.89.0.393774226817.issue45826@roundup.psfhosted.org>
2021-11-17 04:37:46Dennis Sweeneylinkissue45826 messages
2021-11-17 04:37:46Dennis Sweeneycreate