SystemError in RSocket__setblocking (Travis CI)

Create issue
Issue #3049 resolved
Mahmoud Hashemi created an issue

Hey all! So Travis recently updated their default image, and the pypy used there (Python 2.7.13 (8cdda8b8cdb8, Apr 14 2019, 14:06:44) [PyPy 7.1.1 with GCC 6.2.0 20160901]) gives me this issue:

SystemError: unexpected internal exception (please report a bug): <CSocketError object at 0x6922eb0>; internal traceback was dumped to stderr

RPython traceback:
File "pypy_interpreter.c", line 40143, in BuiltinCode2_fastcall_2
File "implement_11.c", line 13173, in fastfunc_settimeout_w_2
File "pypy_module__socket.c", line 2293, in W_Socket_settimeout_w
File "rpython_rlib.c", line 59823, in RSocket__setblocking

The full pytest run can be seen here: https://travis-ci.org/mahmoud/boltons/jobs/567209873

Attempting to reproduce locally, I confirmed the value of timeout there is 10. However there's no expection raised. Locally I'm using the Ubuntu PPA version: Python 2.7.13 (7.0.0+dfsg-1~ppa1~ubuntu16.04, Feb 07 2019, 20:56:09) / [PyPy 7.0.0 with GCC 5.4.0 20160609] on linux2

Maybe I should pick this up with Travis, but I figured if it’s affecting me, and Travis just updated the defaults, you may be seeing more of these in future. Thanks in advance for any help!

Comments (4)

  1. Mark Williams

    Minimal reproducer:

    import socket
    a, _ = socket.socketpair()
    a.close()
    a.settimeout(1)
    

    Offending code seems to be:

    https://bitbucket.org/pypy/pypy/commits/2ea6562691b9bc55ae570daaa61e913db8668fc6#Lrpython/rlib/rsocket.pyT571

    This won’t occur with the object returned by socket.socket() because its close() method removes the underlying _socket, so the settimeout(1) call can't invoke fcntl on an fd of -1.

    The error seems to imply that _rsocket_ffi.socketpair isn't saving errno, but it's declared with save=SAVE_ERR.

  2. Mark Williams

    Note that the reproducer does not raise an EBADF exception on CPython 2, but does on Python 3.6+ and PyPy 3.6 beta (784b254d669919c872a505b807db8462b6140973). That implies something's missing from the backport, and that the right thing to do would be to silently ignore EBADF in RSocket._setblocking in PyPy’s 2.7 implementation.

  3. Armin Rigo

    This won't occur with socket.socket() because that function wraps the returned socket inside the class provided by the pure-Python socket.py, whereas for some reason socket.socketpair() does not.

    Like you have found, it turns out that socket.settimeout() and socket.setblocking() always ignore all errors in CPython 2. Getting the RPython-level exception from rsocket.py is fine, but the code is missing catching that in pypy.module._socket.interp_socket (as it must, to either convert the exception into an app-level socket.error or, as here, to ignore it). I've done it in 8819acbf633a, and merged into the py3.6 branch where these two functions no longer ignore errors. Thanks!

  4. Log in to comment