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

libuv 1.48.0: getaddrinfo('', 0): OSError: [Errno 22] Invalid argument #596

Open
hroncok opened this issue Feb 27, 2024 · 6 comments
Open

Comments

@hroncok
Copy link
Contributor

hroncok commented Feb 27, 2024

  • uvloop version: 0.19.0
  • Python version: 3.12.2
  • Platform: Fedora Linux 41
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?: yes
  • Does uvloop behave differently from vanilla asyncio? How?: yes, see details

We are trying to update the Fedora uvloop package to 0.19.0 with Cython 3 and #587 but I was able to reproduce the failure with cython 0.29.x as well.

The tests initially passed 24 days ago with libuv 1.47.0, but now they fail with libuv 1.48.0:

=================================== FAILURES ===================================
________________________ Test_UV_DNS.test_getaddrinfo_8 ________________________
Traceback (most recent call last):
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 33, in _test_getaddrinfo
    a1 = socket.getaddrinfo(*args, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/socket.py", line 963, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.12/unittest/case.py", line 58, in testPartExecutor
    yield
  File "/usr/lib64/python3.12/unittest/case.py", line 634, in run
    self._callTestMethod(testMethod)
  File "/usr/lib64/python3.12/unittest/case.py", line 589, in _callTestMethod
    if method() is not None:
       ^^^^^^^^
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 107, in test_getaddrinfo_8
    self._test_getaddrinfo('', 0)
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 48, in _test_getaddrinfo
    raise ex
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 38, in _test_getaddrinfo
    a2 = self.loop.run_until_complete(
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1516, in uvloop.loop.Loop.run_until_complete
  File "uvloop/loop.pyx", line 1527, in getaddrinfo
OSError: [Errno 22] Invalid argument
________________________ Test_UV_DNS.test_getaddrinfo_9 ________________________
Traceback (most recent call last):
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 33, in _test_getaddrinfo
    a1 = socket.getaddrinfo(*args, **kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/socket.py", line 963, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib64/python3.12/unittest/case.py", line 58, in testPartExecutor
    yield
  File "/usr/lib64/python3.12/unittest/case.py", line 634, in run
    self._callTestMethod(testMethod)
  File "/usr/lib64/python3.12/unittest/case.py", line 589, in _callTestMethod
    if method() is not None:
       ^^^^^^^^
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 111, in test_getaddrinfo_9
    self._test_getaddrinfo(b'', 0)
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 48, in _test_getaddrinfo
    raise ex
  File "/builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_dns.py", line 38, in _test_getaddrinfo
    a2 = self.loop.run_until_complete(
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1516, in uvloop.loop.Loop.run_until_complete
  File "uvloop/loop.pyx", line 1527, in getaddrinfo
OSError: [Errno 22] Invalid argument
=============================== warnings summary ===============================
_empty/tests/test_aiohttp.py::Test_UV_AioHTTP::test_aiohttp_graceful_shutdown
  /builddir/build/BUILD/uvloop-0.19.0/_empty/tests/test_aiohttp.py:81: NotAppKeyWarning: It is recommended to use web.AppKey instances for keys.
  https://docs.aiohttp.org/en/stable/web_advanced.html#application-s-config
    app['websockets'] = weakref.WeakSet()

_empty/tests/test_aiohttp.py::Test_UV_AioHTTP::test_aiohttp_graceful_shutdown
  /usr/lib64/python3.12/site-packages/aiohttp/web_runner.py:95: DeprecationWarning: shutdown_timeout should be set on BaseRunner
    super().__init__(

_empty/tests/test_executors.py::TestUVExecutors::test_executors_process_pool_01
_empty/tests/test_executors.py::TestAIOExecutors::test_executors_process_pool_01
_empty/tests/test_regr1.py::TestIssue39Regr::test_issue39_regression
  /usr/lib64/python3.12/multiprocessing/popen_fork.py:66: DeprecationWarning: This process (pid=800) is multi-threaded, use of fork() may lead to deadlocks in the child.
    self.pid = os.fork()

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_8 - OSError: [Errno 2...
FAILED tests/test_dns.py::Test_UV_DNS::test_getaddrinfo_9 - OSError: [Errno 2...
====== 2 failed, 472 passed, 28 skipped, 5 warnings in 105.04s (0:01:45) =======

I've checked the tests and they call getaddrinfo('', 0). Our build runs offline.

socket exception:

>>> socket.getaddrinfo('', 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.12/socket.py", line 963, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

vanilla asyncio exception:

>>> async def f_asyncio():
...  loop = asyncio.get_running_loop()
...  return await loop.getaddrinfo('', 0)
... 
>>> asyncio.run(f_asyncio())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 685, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "<stdin>", line 3, in f_asyncio
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 899, in getaddrinfo
    return await self.run_in_executor(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 882, in _getaddrinfo_debug
    addrinfo = socket.getaddrinfo(host, port, family, type, proto, flags)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/socket.py", line 963, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known

uvloop exception:

>>> async def f_uvloop():
...  loop = uvloop.new_event_loop()
...  return await loop.getaddrinfo('', 0)
... 
>>> asyncio.run(f_uvloop())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/asyncio/base_events.py", line 685, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "<stdin>", line 3, in f_uvloop
  File "uvloop/loop.pyx", line 1527, in getaddrinfo
OSError: [Errno 22] Invalid argument
@hroncok

This comment was marked as resolved.

@hroncok

This comment was marked as resolved.

@hroncok hroncok changed the title getaddrinfo('', 0): OSError: [Errno 22] Invalid argument libuv 1.48.0: getaddrinfo('', 0): OSError: [Errno 22] Invalid argument Feb 27, 2024
@hroncok
Copy link
Contributor Author

hroncok commented Feb 27, 2024

Looks like libuv/libuv@3530bcc might cause this.

@hroncok
Copy link
Contributor Author

hroncok commented Feb 27, 2024

git bisect agrees

@ancieg
Copy link

ancieg commented Apr 12, 2024

Looks like libuv/libuv@3530bcc might cause this.

Looks like it is expected behavior for now, so I suggest simply skip these tests for libuv >= 1.48.0:

From 9373f66795862cb2879699ae3f83b09834697feb Mon Sep 17 00:00:00 2001
From: Anton Zhukharev <ancieg@altlinux.org>
Date: Fri, 12 Apr 2024 14:44:38 +0300
Subject: [PATCH] src: fix tests for libuv >= 1.48.0

---
 tests/test_dns.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/test_dns.py b/tests/test_dns.py
index f61b1e8..e304960 100644
--- a/tests/test_dns.py
+++ b/tests/test_dns.py
@@ -3,6 +3,7 @@ import socket
 import unittest

 from uvloop import _testbase as tb
+from uvloop.loop import libuv_get_version


 def patched_getaddrinfo(*args, **kwargs):
@@ -103,10 +104,12 @@ class BaseTestDNS:
         self._test_getaddrinfo(None, 0)
         self._test_getaddrinfo(None, 0, type=socket.SOCK_STREAM)

+    @unittest.skipIf(libuv_get_version() >= 0x013000, 'Must fail with libuv >= 1.48.0')
     def test_getaddrinfo_8(self):
         self._test_getaddrinfo('', 0)
         self._test_getaddrinfo('', 0, type=socket.SOCK_STREAM)

+    @unittest.skipIf(libuv_get_version() >= 0x013000, 'Must fail with libuv >= 1.48.0')
     def test_getaddrinfo_9(self):
         self._test_getaddrinfo(b'', 0)
         self._test_getaddrinfo(b'', 0, type=socket.SOCK_STREAM)
--
2.42.1

@fantix
Copy link
Member

fantix commented Aug 15, 2024

This is fixed in #600

fantix added a commit that referenced this issue Aug 15, 2024
Changes
=======

* Upgrade libuv to v1.48.0 (#600)
  (by @niklasr22 @fantix in 7777852 for #596 #615)

Fixes
=====

* Fix test_create_server_4 with Python 3.12.5 (#614)
  (by @shadchin in 62f9239)

* Use len(os.sched_getaffinity(0)) instead of os.cpu_count() (#591)
  (by @avkarenow in c8531c2 for #591)

* Inline _Py_RestoreSignals() from CPython (#604)
  (by @befeleme in 8511ba1 for #603)
@fantix fantix mentioned this issue Aug 15, 2024
edgarrmondragon pushed a commit to edgarrmondragon/uvloop that referenced this issue Aug 19, 2024
Changes
=======

* Upgrade libuv to v1.48.0 (MagicStack#600)
  (by @niklasr22 @fantix in 7777852 for MagicStack#596 MagicStack#615)

Fixes
=====

* Fix test_create_server_4 with Python 3.12.5 (MagicStack#614)
  (by @shadchin in 62f9239)

* Use len(os.sched_getaffinity(0)) instead of os.cpu_count() (MagicStack#591)
  (by @avkarenow in c8531c2 for MagicStack#591)

* Inline _Py_RestoreSignals() from CPython (MagicStack#604)
  (by @befeleme in 8511ba1 for MagicStack#603)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants