https://bugs.winehq.org/show_bug.cgi?id=42377
Bug ID: 42377 Summary: WSASend() returns invalid number of bytes when both lpOverlapped and lpNumberOfBytesSent Product: Wine Version: 2.0-rc5 Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: zbr@ioremap.net Distribution: ---
Created attachment 57161 --> https://bugs.winehq.org/attachment.cgi?id=57161 WINEDEBUG=+all ./grtest_server
Golang uses overlapped sockets, but sets both lpOverlapped and lpNumberOfBytesSent. Sometimes lpNumberOfBytesSent is returned to be higher than number of bytes in the buffer to be sent, this breaks overlapped state machine in golang, which eventually ends up with error and connection reset.
Bug is 100% reproducible, but it requires quite a setup. First, golang uses memory mapped page hack to get time structures. These are not updated by wine (see the bug here: https://bugs.winehq.org/show_bug.cgi?id=29168). To fix it I made a patch for golang which falls back to QPC timings if startup code detects timer is stalled, see patches and discussion: https://go-review.googlesource.com/#/c/35710/ https://github.com/golang/go/issues/18537
After golang has been patched, I use this test case to compile a grpc server and python client: https://github.com/bioothod/grpc_test
# edit Makefile to specify golang path and root directory $ make windows $ wine ./grpc_server $ python client.py ...
Running multiple clients 100% ends up with connection close errors, which I debugged to incorrect (larger than the buffer size) lpNumberOfBytesSent
Here is a discussion: https://github.com/golang/go/issues/18887
Turning overlapped feature off (by setting lpOverlapped to NULL) resolves the bug, but as far as I understand it ends up with blocked WSASend() call, who will wait for buffer to be completely sent, which is kind of undesired behaviour.
Attached WINEDEBUG=+all ./grtest_server log if it helps.