https://bugs.winehq.org/show_bug.cgi?id=38980
Stefan Dösinger stefan@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |stefan@codeweavers.com
--- Comment #8 from Stefan Dösinger stefan@codeweavers.com --- The downloader uses libtorrent. I can reproduce spurious crashes with my own libtorrent debug build using their client_test.exe example. So much easier to debug than banging the head against boost in binary form :-) . I don't know if it is exactly the same crash because I am dying on an assert that is presumably compiled out in a production build, but the backtrace looks very similar to what Anastasius Focht found and without the assert I'd expect the code in question to die a few lines later.
The reason for the crash is that peer_connection::on_receive_data in libtorrent/src/peer_connection.cpp is called with an invalid (=NULL) this pointer. The call comes from boost.
The Wine log (+my stderr debug messages in libtorrent) show this:
003e:trace:winsock:WS2_recv_base socket 00f8, wsabuf 0xf3f054, nbufs 1, flags 0, from 0x0, fromlen -1, ovl 0x5d6d318, func 0x0 003e:trace:winsock:WS2_recv_base fd=72, options=0 003e:warn:winsock:wsaErrno errno 54, (Connection reset by peer). 003e:warn:winsock:WS2_recv_base -> ERROR 10054 003e:trace:sync:PostQueuedCompletionStatus 0x2c 0 00000002 0x5d6d318 <snip> 003e:trace:sync:GetQueuedCompletionStatus Success, key=0, overlapped=0x5d6d318 003e:trace:sync:GetQueuedCompletionStatus setting error 3221225997 on_receive_data, this=05D6D0F0 survived assert, this=05D6D0F0 003e:trace:winsock:WS_closesocket (socket 00f8) -> 0 003e:trace:sync:GetQueuedCompletionStatus (0x2c,0xf3f564,0xf3f55c,0xf3f560,-1) 003e:trace:sync:GetQueuedCompletionStatus Success, key=2, overlapped=0x5d6d318 on_receive_data, this=00000000
This is the only occurence of the pointer 0x5d6d318 in the entire log. It seems that WS2_recv returns an error, causing boost to call PostQueuedCompletionStatus with dwCompletionKey=2 (win_iocp_socket_service.ipp). Yet apparently something (hint: our WS2_recv) enqueues an IO completion status with dwCompletionKey=0 and the same overlapped pointer. If I understand the documentation right it is not supposed to enqueue anything if it returns an error. Then boost dequeues a result from the same operation twice. The first operation "works", although probably passes junk data to libtorrent. Then it discards private data stored in 0x5d6d318. When the same operation returns a result again (the right one, with completion key 2) the callback goes wrong.
I don't have a fix yet and the theory could be completely wrong. I'll continue on this bug later.