-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
select.ipoll can crash micropython with nonblocking sockets in an error state #3164
Comments
Thanks for the report. I can't reproduce your exact error but I can find 2 related issues. Here is a minimal test script: try:
import usocket as socket
except:
import socket
try:
import uselect as select
except:
import select
def do_client(ip, port):
addr = socket.getaddrinfo(ip, port)[0][-1]
s = socket.socket()
s.setblocking(False)
try:
s.connect(addr)
print("connect done")
except OSError as e:
print("connect", e)
p = select.poll()
p.register(s, select.POLLERR | select.POLLOUT | select.POLLIN | select.POLLHUP)
for event in p.poll(-1):
print("event:", event)
if event[1] & select.POLLOUT:
print("new connection")
try:
s.send(b'some data')
print('send succeeded')
except OSError as e:
print("send failed:", e)
do_client('<any valid IP address>', 12345) You can run it on CPython, uPy unix and uPy esp8266. On CPython and uPy unix it has the following result:
This means: the connection was in progress, poll returned a POLLOUT event, but when trying to send data there is an ECONNREFUSED error (since port 12345 is invalid, but the IP address is valid). On esp8266 it gives:
So it allows to send data even though the connection is not established. The problem seems to be that lwip allows to send TCP data even if the socket is not yet connected. The second issue (which seems more related to the original report above) is the following: take the same test script above and remove the
while on esp8266 it gives:
There are 2 issues here: lwip is returning ECONNRESET instead of ECONNREFUSED, and polling of a socket in this state leads to a crash. |
The issue with crashing when polling a closed/invalid socket is due to |
The issue with crashing on poll was fixed by 318f874 The other issues with wrong error codes and error behaviour still remain. |
Confirm, crash gone. |
[Edit] Turns out this error occurs only if set socket.setblocking(False). No error occurs if blocking socket are set. I'm no expert, so it might be something trivial I'm missing. I think this issue might have been back in v1.10. Please check the output of the @dpgeorge example code:
|
@varna9000 as mentioned above, the crash is fixed but the other issues are not. It doesn't look like you are seeing a crash, so the error is not back. |
Disable existing native networking.
Under certain conditions select.ipoll can crash.
Attached is a module that has two functions: One to set up a testbed-server and one as a testbed-client.
I've installed this on two Wemos-D1 mini pro's. On the first one I run the server (just for setting up the wifi)
On the second one I run a client, that opens two nonblocking sockets, trying to connect to the server on the wrong port (81 instead of 80).
The sockets enter an error state due to the wrong port and the client fails to remove them from the poll object.
On the next ipoll() micropython crashes, the esp8266 resets.
For some reason I can't attach the code as an attachment - sorry, I have to paste it here:
The text was updated successfully, but these errors were encountered: