hamedramzi / libtorrent

Automatically exported from code.google.com/p/libtorrent
Other
0 stars 0 forks source link

assert fail with 0.16.12 (boost 1_45) #544

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Is this a issue? how to fix it? Thanks!

#0  0x4011c992 in ?? () from /home/mike/proj/test/obj/local/armeabi-v7a/libc.so
#1  0x4011a074 in abort () from 
/home/mike/proj/test/obj/local/armeabi-v7a/libc.so
#2  0x5f853614 in assert_fail (expr=0x5faf94ec "p->num_transmissions < 
m_sm->num_resends() + 1", line=1765, file=0x5faf9298 "utp_stream.cpp", 
function=0x5fd58710 "bool 
libtorrent::utp_socket_impl::resend_packet(libtorrent::packet*, bool)", 
value=0x0) at assert.cpp:243
#3  0x5f917238 in libtorrent::utp_socket_impl::resend_packet (this=0x5c86e210, 
p=0x5c7f0560, fast_resend=<optimized out>) at utp_stream.cpp:1765
#4  0x5f9173e2 in libtorrent::utp_socket_impl::parse_sack (this=0x5c86e210, 
packet_ack=<optimized out>, ptr=<optimized out>, size=<optimized out>, 
acked_bytes=0x6056ea60, now=..., min_rtt=@0x6056ea64) at utp_stream.cpp:1404
#5  0x5f9194d4 in libtorrent::utp_socket_impl::incoming_packet (this=<optimized 
out>, buf=0x5c74d250 "!\001\256*>\023@p\334#:2", size=26, ep=..., 
receive_time=...) at utp_stream.cpp:2383
#6  0x5f91596c in libtorrent::utp_socket_manager::incoming_packet 
(this=0x5c753100, p=0x5c74d250 "!\001\256*>\023@p\334#:2", size=26, ep=...) at 
utp_socket_manager.cpp:282
#7  0x5f870c4c in libtorrent::aux::session_impl::on_receive_udp 
(this=0x5c752008, e=..., ep=..., buf=0x5c74d250 "!\001\256*>\023@p\334#:2", 
len=26) at session_impl.cpp:2582
#8  0x5f880938 in operator() (p=0x5c752008, this=<optimized out>, a4=26, 
a2=<optimized out>, a1=<optimized out>, a3=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/mem_fn_template.hpp:
506
#9  operator()<boost::_mfi::mf4<void, libtorrent::aux::session_impl, const 
boost::system::error_code&, const 
boost::asio::ip::basic_endpoint<boost::asio::ip::udp>&, char const*, int>, 
boost::_bi::list4<const boost::system::error_code&, const 
boost::asio::ip::basic_endpoint<boost::asio::ip::udp>&, char const*&, int&> > 
(a=<synthetic pointer>, f=<optimized out>, this=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/bind.hpp:525
#10 operator()<const boost::system::error_code, const 
boost::asio::ip::basic_endpoint<boost::asio::ip::udp>, char const*, int> 
(a2=<optimized out>, a1=<optimized out>, this=<optimized out>, a3=<optimized 
out>, a4=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/bind_template.hpp:14
5
#11 
boost::detail::function::void_function_obj_invoker4<boost::_bi::bind_t<void, 
boost::_mfi::mf4<void, libtorrent::aux::session_impl, boost::system::error_code 
const&, boost::asio::ip::basic_endpoint<boost::asio::ip::udp> const&, char 
const*, int>, 
boost::_bi::list5<boost::_bi::value<libtorrent::aux::session_impl*>, 
boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4> > >, void, 
boost::system::error_code const&, 
boost::asio::ip::basic_endpoint<boost::asio::ip::udp> const&, char const*, 
int>::invoke (function_obj_ptr=<optimized out>, a0=<optimized out>, 
a1=<optimized out>, a2=<optimized out>, a3=26) at 
/home/mike/proj/test/torrent/boost/build/include/boost/function/function_templat
e.hpp:153
#12 0x5f8fbc8c in operator() (a3=<optimized out>, a2=<optimized out>, a1=..., 
a0=..., this=0x5c752ce8) at 
/home/mike/proj/test/torrent/boost/build/include/boost/function/function_templat
e.hpp:1013
#13 libtorrent::udp_socket::on_read (this=0x5c752ce8, s=0x5c752d0c, e=..., 
bytes_transferred=<optimized out>) at udp_socket.cpp:419
#14 0x5f8fee06 in operator() (a3=26, a1=<optimized out>, p=0x5c752ce8, 
this=0x6056edcc, a2=...) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/mem_fn_template.hpp:
393
#15 operator()<boost::_mfi::mf3<void, libtorrent::udp_socket, 
boost::asio::basic_datagram_socket<boost::asio::ip::udp>*, const 
boost::system::error_code&, unsigned int>, boost::_bi::list2<const 
boost::system::error_code&, unsigned int const&> > (a=<synthetic pointer>, 
f=..., this=0x6056edd4) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/bind.hpp:457
#16 operator()<boost::system::error_code, unsigned int> (a1=..., 
this=0x6056edcc, a2=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/bind_template.hpp:10
2
#17 operator() (this=0x6056edcc) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/bind_handler.
hpp:97
#18 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, 
boost::_mfi::mf3<void, libtorrent::udp_socket, 
boost::asio::basic_datagram_socket<boost::asio::ip::udp>*, 
boost::system::error_code const&, unsigned int>, 
boost::_bi::list4<boost::_bi::value<libtorrent::udp_socket*>, 
boost::_bi::value<boost::asio::basic_datagram_socket<boost::asio::ip::udp>*>, 
boost::arg<1>, boost::arg<2> > >, boost::system::error_code, unsigned int> > 
(function=...) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/handler_invoke_hook.
hpp:64
#19 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, 
boost::_mfi::mf3<void, libtorrent::udp_socket, 
boost::asio::basic_datagram_socket<boost::asio::ip::udp>*, 
boost::system::error_code const&, unsigned int>, 
boost::_bi::list4<boost::_bi::value<libtorrent::udp_socket*>, 
boost::_bi::value<boost::asio::basic_datagram_socket<boost::asio::ip::udp>*>, 
boost::arg<1>, boost::arg<2> > >, boost::system::error_code, unsigned int>, 
boost::_bi::bind_t<void, boost::_mfi::mf3<void, libtorrent::udp_socket, 
boost::asio::basic_datagram_socket<boost::asio::ip::udp>*, 
boost::system::error_code const&, unsigned int>, 
boost::_bi::list4<boost::_bi::value<libtorrent::udp_socket*>, 
boost::_bi::value<boost::asio::basic_datagram_socket<boost::asio::ip::udp>*>, 
boost::arg<1>, boost::arg<2> > > > (function=..., context=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/handler_invok
e_helpers.hpp:39
#20 
boost::asio::detail::reactive_socket_recvfrom_op<boost::asio::mutable_buffers_1,
 boost::asio::ip::basic_endpoint<boost::asio::ip::udp>, 
boost::_bi::bind_t<void, boost::_mfi::mf3<void, libtorrent::udp_socket, 
boost::asio::basic_datagram_socket<boost::asio::ip::udp, 
boost::asio::datagram_socket_service<boost::asio::ip::udp> >*, 
boost::system::error_code const&, unsigned int>, 
boost::_bi::list4<boost::_bi::value<libtorrent::udp_socket*>, 
boost::_bi::value<boost::asio::basic_datagram_socket<boost::asio::ip::udp, 
boost::asio::datagram_socket_service<boost::asio::ip::udp> >*>, boost::arg<1>, 
boost::arg<2> > > >::do_complete (owner=<optimized out>, base=<optimized out>) 
at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/reactive_sock
et_recvfrom_op.hpp:116
#21 0x5f84efde in complete (owner=..., this=0x5c7d5d40) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/task_io_servi
ce_operation.hpp:35
#22 boost::asio::detail::task_io_service::do_one (this=0x5c74ce90, lock=..., 
this_idle_thread=0x6056ee7c) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/impl/task_io_
service.ipp:278
#23 0x5f84fc7c in boost::asio::detail::task_io_service::run (this=0x5c74ce90, 
ec=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/impl/task_io_
service.ipp:130
#24 0x5f87f648 in libtorrent::aux::session_impl::main_thread (this=0x5c752008) 
at session_impl.cpp:4756
#25 0x5f881516 in operator() (p=<optimized out>, this=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/mem_fn_template.hpp:
49
#26 operator()<boost::_mfi::mf0<void, libtorrent::aux::session_impl>, 
boost::_bi::list0> (f=<optimized out>, this=<optimized out>, a=<optimized out>) 
at /home/mike/proj/test/torrent/boost/build/include/boost/bind/bind.hpp:253
#27 operator() (this=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/bind/bind_template.hpp:20
#28 boost::asio::detail::posix_thread::func<boost::_bi::bind_t<void, 
boost::_mfi::mf0<void, libtorrent::aux::session_impl>, 
boost::_bi::list1<boost::_bi::value<libtorrent::aux::session_impl*> > > >::run 
(this=<optimized out>) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/posix_thread.
hpp:82
#29 0x5f84a642 in boost::asio::detail::boost_asio_detail_posix_thread_function 
(arg=0x5c74daf0) at 
/home/mike/proj/test/torrent/boost/build/include/boost/asio/detail/impl/posix_th
read.ipp:64
#30 0x401103dc in __thread_entry () from 
/home/mike/proj/test/obj/local/armeabi-v7a/libc.so
#31 0x4010fac8 in pthread_create () from 
/home/mike/proj/test/obj/local/armeabi-v7a/libc.so
#32 0x00000000 in ?? ()

Original issue reported on code.google.com by ygao....@gmail.com on 8 Nov 2013 at 8:36

GoogleCodeExporter commented 9 years ago
I ran into this same assertion in 0.16.12 and have spent some time looking for 
the cause.  I'm not certain I've found it but I did spot something suspicious.

The asserted condition is (p->num_transmissions < m_sm->num_resends() + 1).  
The num_resends() function just returns a session_level setting so it can be 
assumed to be constant.  Adding one accounts for the number of possible 
fast_resends made for the packet.  Thus the only way the condition can fail is 
if p->num_transmissions exceeds some constant.

num_transmissions is only incremented in one place: resend_packet(), line 1770. 
 It represents the number of times the packet has been sent or re-sent.

resend_packet() returns a boolean to indicate whether the packet was indeed 
re-sent.  There's an early exit from the function at line 1760, returning 
false; after which the assertion is checked at 1765 and num_transmissions is 
incremented at 1770.  In 1786 the packet is sent, and the error code from that 
operation is checked at 1801 and if send_packet() produced an error then 
resend_packet() returns false at 1806; if no error then it returns true at 1809.

The suspicious bit is that parse_sack() uses the return value of 
resend_packet() at line 1404 to break out of a loop that increments 
m_fast_resend_seq_nr after each iteration.  Suppose that the send_packet() call 
in line 1786 of resend_packet() produces an error; then resend_packet() will 
have incremented num_transmissions but returned false, and parse_sack() will 
break out of the loop without incrementing m_fast_resend_seq_nr.  This will 
cause the packet to still be in the fast_resend range but with an increased 
num_transmissions.  If there are several fast_resend attempts in a row with 
failed send_packet() calls, then the limit could be exceeded.

Like I said, I'm not confident this is the actual cause but it might be worth a 
close look.  If it is the cause, a possible fix would be to decrement 
num_transmissions within the error code handling block within resend_packet(), 
to reflect that the packet was in fact not successfully re-sent.

Original comment by alan...@gmail.com on 11 Nov 2013 at 6:33

GoogleCodeExporter commented 9 years ago
I should add that I've had difficulty reproducing the assertion for debugging 
purposes.  It's one of those that's rare enough to be hard to replicate, but 
frequent enough to be an impediment.

Original comment by alan...@gmail.com on 11 Nov 2013 at 6:44

GoogleCodeExporter commented 9 years ago
Update: I have been able to reproduce the assertion although it takes many 
hours of running libtorrent for it to occur.  Unfortunately, my suggested fix 
(to decrement num_transmissions when the send_packet() call in resend_packet() 
fails) did not prevent the assertion from occurring.

Original comment by alan...@gmail.com on 15 Nov 2013 at 11:49

GoogleCodeExporter commented 9 years ago
Thank you very much for your effort. I just comment out it. Will it
generate new issue without it?

Original comment by ygao....@gmail.com on 16 Nov 2013 at 3:07