python-udsoncan: Socket timeout when trying to send data on second socket

Hi,

I’m currently facing a quite systematic issue when using 2 different sockets to send UDS data on the same bus.

The stack trace ends like this:

    IsoTPSocketConnection.send(self, data)
  File "/venv/lib/python3.8/site-packages/udsoncan/connections.py", line 65, in send
    self.specific_send(payload)
  File "/venv/lib/python3.8/site-packages/udsoncan/connections.py", line 321, in specific_send
    self.tpsock.send(payload)
  File "/venv/lib/python3.8/site-packages/isotp/tpsock/__init__.py", line 89, in send
    return self._socket.send(*args, **kwargs)
socket.timeout: timed out
  • I’m running Ubuntu 20.04LTS and the issue appeared after kernel update from 5.15.0-78-generic to 5.15.0-79-generic.
  • I also reproduced the issue with Ubuntu 22.04 LTS after update from 5.19.0-45-generic to 6.2.0-33-generic.
  • Moving back to old kernels restores the good behavior.

In details, the aim of my project is to simulate UDS conversation then:

  • opening a socket to simulate UDS requests
  • opening a second socket to simulate the answers

The 2 sockets are opened successfully, the first one sends the request, the second one raises an exception when trying to send.

This setup was working well with old kernels but with recent ones, the timeout is very frequent but not systematic.

I tried without success:

  • to update all python libs linked to can communication (udsoncan, can-isotp, python-can, msgpack 0.6.2)
  • to install most recent kernel, with the hope to get it fixed

Could you help me to identify the component which introduced this “issue”? I’m not familiar with the different layers in action for this topic:

  • python libs
  • kernel modules
  • kernel core

Thanks in advance, best regards,

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 24 (12 by maintainers)

Commits related to this issue

Most upvoted comments

That’s good to know, thanks for the clarification @hartkopp

Ok @lumagi , than it makes sense that the issue relates to your fix!

But the CPython implementation should not act against the users expectation and exchange syscalls without notice. I assume this is used for multi-threading.

Please also consider this. I originally did a bit of digging in the CPython source code because I just assumed Python would pass the send/recv calls directly to libC. But instead, it always configures the sockets to be nonblocking and uses poll to implement blocking semantics for its sockets.

Edit: this is the main loop that does the polling (or rather select) until the socket is ready.

I think this might be related to this bug report. It’s a race condition in the kernel module that causes the send to time out if there’s a second thread listening on the same socket. There’s a patch for the bug here. Maybe you want to try this, but it involves recompiling the isotp module.