Hi we're build a proof of concept version of our application that uses the UDT.net wrapper (https://code.google.com/p/udt-net/) but we're seeing an access violation when testing our reconnect logic that we've migrated from TCP. When a reconnect fails we get an access violation here:
UdtProtocol.dll!std::_Tree<std::_Tset_traits<int,std::less<int>,std::allocator<int>,0> >::begin() Line 807 + 0xc bytes C++
UdtProtocol.dll!CEPoll::update_events(const int & uid, std::set<int,std::less<int>,std::allocator<int> > & eids, int events, bool enable) Line 345 + 0xc bytes C++
UdtProtocol.dll!CRendezvousQueue::updateConnStatus() Line 849 C++
UdtProtocol.dll!CRcvQueue::worker(void * param) Line 1091 C++
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!_RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!RtlUserThreadStart@8() + 0x1b bytes
This is occuring because we have a destroyed instance of CUDT in m_lRendezvousID which has not been removed due to the following code. During the failed connect m_bConnecting gets set to false in CRendezvousQueue::updateConnStatus():
if (CTimer::getTime() >= i->m_ullTTL)
{
// connection timer expired, acknowledge app via epoll
i->m_pUDT->m_bConnecting = false;
And this means that when we come to close the socket, we fail to remove it from the connector datastructure (see :CUDT::close())
if (m_bListening)
{
m_bListening = false;
m_pRcvQueue->removeListener(this);
}
else if (m_bConnecting)
{
m_pRcvQueue->removeConnector(m_SocketID);
}
I noticed that this was a recent change, and if I rollback the change in revision 1.160 of core.cpp on my local build the issue goes away. Presumably this brings back the issue that this fix solved.
Please let me know if you can think of a better fix or if there is another way to work around this issue?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have the same problem.
This is my test case which will cause access violation like the post above:
- Create an udt socket then make a connection and add to udt epoll (this connection will never reach because server not listen to UDT connection). Before the connetion timeout -> close UDT socket -> about 1 or 2 seconds later the garbage collection will free the UDT class object but in another thread still hold and access to the freed UDT class object (UdtProtocol.dll!CRendezvousQueue::updateConnStatus() Line 849 C++) -> this cause an access violation.
Sorry for my weakness of english writing skill.
Thank you very much.
Last edit: Duy 2015-08-15
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi we're build a proof of concept version of our application that uses the UDT.net wrapper (https://code.google.com/p/udt-net/) but we're seeing an access violation when testing our reconnect logic that we've migrated from TCP. When a reconnect fails we get an access violation here:
UdtProtocol.dll!std::_Tree<std::_Tset_traits<int,std::less<int>,std::allocator<int>,0> >::begin() Line 807 + 0xc bytes C++
UdtProtocol.dll!CEPoll::update_events(const int & uid, std::set<int,std::less<int>,std::allocator<int> > & eids, int events, bool enable) Line 345 + 0xc bytes C++
This is occuring because we have a destroyed instance of CUDT in m_lRendezvousID which has not been removed due to the following code. During the failed connect m_bConnecting gets set to false in CRendezvousQueue::updateConnStatus():
And this means that when we come to close the socket, we fail to remove it from the connector datastructure (see :CUDT::close())
if (m_bListening)
{
m_bListening = false;
m_pRcvQueue->removeListener(this);
}
else if (m_bConnecting)
{
m_pRcvQueue->removeConnector(m_SocketID);
}
I noticed that this was a recent change, and if I rollback the change in revision 1.160 of core.cpp on my local build the issue goes away. Presumably this brings back the issue that this fix solved.
Please let me know if you can think of a better fix or if there is another way to work around this issue?
I have the same problem.
This is my test case which will cause access violation like the post above:
- Create an udt socket then make a connection and add to udt epoll (this connection will never reach because server not listen to UDT connection). Before the connetion timeout -> close UDT socket -> about 1 or 2 seconds later the garbage collection will free the UDT class object but in another thread still hold and access to the freed UDT class object (UdtProtocol.dll!CRendezvousQueue::updateConnStatus() Line 849 C++) -> this cause an access violation.
Sorry for my weakness of english writing skill.
Thank you very much.
Last edit: Duy 2015-08-15
I have the same problem.
How have you resolved it?
Same problem with latest version 4.11
I think I found it: when the connection times out, it does not get removed from the "rendezvous queue".
Fix: add the "m_pRcvQueue->removeConnector(m_SocketID);" command as shown here:
or see my fork with the fixed code (+ other fixes and features): https://bitbucket.org/M-1/udt.git
Have a great day!
P.S. Thanks for posting about the issue and describing it. I almost gave up on finding this one...
Last edit: Em One 2016-05-17