STINNER Victor <vstin...@redhat.com> added the comment:

I'm able to reproduce the bug on my Fedora using:

vstinner@apu$ gdb -args ENV/bin/python -m coverage run  --pylib -m test 
--fail-env-changed -uall,-cpu  test_urllib -F
(gdb) run

python: Objects/typeobject.c:3086: _PyType_Lookup: Assertion 
`!PyErr_Occurred()' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7093f2b in raise () from /lib64/libc.so.6

(gdb) py-bt
Traceback (most recent call first):
  <built-in method close of HTTPResponse object at remote 0x7fffe581ff50>
  File "/home/vstinner/prog/python/master/Lib/http/client.py", line 405, in 
close
    super().close() # set "closed" flag
  File "/home/vstinner/prog/python/master/Lib/traceback.py", line 216, in 
clear_frames
    tb.tb_frame.clear()
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 205, in 
__exit__
    traceback.clear_frames(tb)
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 178, in 
handle
    callable_obj(*args, **kwargs)
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 743, in 
assertRaises
    return context.handle('assertRaises', args, kwargs)
  File "/home/vstinner/prog/python/master/Lib/test/test_urllib.py", line 382, 
in test_redirect_limit_independent
    "http://something";)
  (...)

(gdb) where
#0  0x00007ffff7093f2b in raise () from /lib64/libc.so.6
#1  0x00007ffff707e561 in abort () from /lib64/libc.so.6
#2  0x00007ffff707e431 in __assert_fail_base.cold.0 () from /lib64/libc.so.6
#3  0x00007ffff708c692 in __assert_fail () from /lib64/libc.so.6
#4  0x00000000004aa2ea in _PyType_Lookup (type=0xdc1b30, 
name='__IOBase_closed') at Objects/typeobject.c:3086
#5  0x00000000004883ff in _PyObject_GenericSetAttrWithDict (
    obj=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, name='__IOBase_closed', value=True, dict=0x0) at 
Objects/object.c:1292
#6  0x000000000048871a in PyObject_GenericSetAttr (
    obj=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, name='__IOBase_closed', value=True) at Objects/object.c:1340
#7  0x00000000004873a0 in PyObject_SetAttr (
    v=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, name='__IOBase_closed', value=True) at Objects/object.c:977
#8  0x0000000000486f03 in _PyObject_SetAttrId (
    v=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, name=0x9d4330 <PyId___IOBase_closed>, w=True) at 
Objects/object.c:857
#9  0x0000000000625d9c in _io__IOBase_close_impl (
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=---T---Type ---Type 
<return>---Type <ret---Type <ret---Type ---Type ---Type <return>---Type 
<ret---Type <return> to ---Type <return>---Type ---T---Type <return>---Type 
---T---Type <return> to continue, or q <return> to quit---
) at remote 0x7fffe581ff50>) at ./Modules/_io/iobase.c:239
#10 0x0000000000627e12 in _io__IOBase_close (
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, _unused_ignored=0x0) at ./Modules/_io/clinic/iobase.c.h:60
#11 0x0000000000438cb3 in _PyMethodDef_RawFastCallKeywords (method=0x9d4d40 
<iobase_methods+128>, 
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>, args=0x7fffe4e793e8, nargs=0, kwnames=0x0) at 
Objects/call.c:629
#12 0x000000000043910d in _PyCFunction_FastCallKeywords (func=<built-in method 
close of HTTPResponse object at remote 0x7fffe581ff50>, args=0x7fffe4e793e8, 
nargs=0, kwnames=0x0)
    at Objects/call.c:730
#13 0x00000000005500e9 in call_function (pp_stack=0x7ffffffb7da0, oparg=0, 
kwnames=0x0) at Python/ceval.c:4565
#14 0x0000000000548e1d in _PyEval_EvalFrameDefault (
    f=Frame 0x7fffe4e79250, for file 
/home/vstinner/prog/python/master/Lib/http/client.py, line 405, in close 
(self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, 
debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 
0x7fffe553efb0>, _headers=[('Location', 
'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], 
_unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, 
defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, 
version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', 
length=None, will_close=True, code=302, _finalizing=True) at remote 
0x7fffe581ff50>), throwflag=0)
    at Python/ceval.c:3159
(...)


The bug is in _io__IOBase_close_impl(). I modified the code:

    assert(!PyErr_Occurred());

    res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);

    assert(!PyErr_Occurred());     /* <---- THIS ASSERTION FAILS */

    if (_PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True) < 0) {
        Py_XDECREF(res);
        return NULL;
    }

The problem is that _PyObject_SetAttrId() is called while the flush() method 
raised an exception.

We need something like PyErr_Fetch/PyErr_Store to set the attribute.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue34068>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to