From 3a9861e2374e2959eb2c7d54d5e531d175d72626 Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 28 Dec 2017 21:41:46 +0100 Subject: [PATCH] complete the error handling test and make it part of the default simulation test suite. It will run a file transfer between two clients repeatedly, each time cause another memory allocation fail, until every single memory allocation has failed once. Any invariant check failure, assertion or signal will cause the test to fail --- Jamfile | 4 +- appveyor.yml | 6 +- include/libtorrent/aux_/session_impl.hpp | 4 +- include/libtorrent/disk_io_thread.hpp | 2 + include/libtorrent/packet_pool.hpp | 16 +++- include/libtorrent/peer_connection.hpp | 4 +- .../libtorrent/peer_connection_interface.hpp | 2 +- include/libtorrent/torrent.hpp | 2 +- include/libtorrent/tracker_manager.hpp | 2 +- simulation/Jamfile | 4 +- simulation/test_error_handling.cpp | 33 ++++++- src/block_cache.cpp | 1 - src/disk_io_thread.cpp | 13 +-- src/peer_connection.cpp | 26 ++--- src/session_impl.cpp | 17 ++-- src/torrent.cpp | 94 ++++++++++++------- test/test_peer_list.cpp | 4 +- 17 files changed, 144 insertions(+), 90 deletions(-) diff --git a/Jamfile b/Jamfile index a51a9d65b..37c82cdb9 100644 --- a/Jamfile +++ b/Jamfile @@ -519,12 +519,12 @@ variant test_release : release variant test_debug : debug : on full shared - on on multi on + on multi on ; variant test_barebones : debug : off off off off shared off off - on on multi on + on multi on ; variant test_arm : debug : off off off off diff --git a/appveyor.yml b/appveyor.yml index bb3ec7b7d..436a3887f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -88,7 +88,7 @@ build_script: # simulations - cd %ROOT_DIRECTORY%\simulation - if defined sim ( - b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% picker-debugging=on invariant-checks=full variant=%variant% deprecated-functions=off %linkflags% %include% link=shared crypto=built-in testing.execute=off + b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in define=BOOST_ASIO_DISABLE_IOCP testing.execute=off ) test_script: @@ -107,7 +107,9 @@ test_script: # specifiers when debug iterators are enabled. Specifically, constructors that # allocate memory are still marked as noexcept. That results in program # termination +# the IOCP backend in asio appears to have an issue where it hangs under +# certain unexpected terminations (through exceptions) - cd %ROOT_DIRECTORY%\simulation - if defined sim ( - b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in + b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=off picker-debugging=on invariant-checks=full test_debug %linkflags% %include% boost-link=default link=static crypto=built-in define=BOOST_ASIO_DISABLE_IOCP ) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 88f33985f..6b5a036a1 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -1261,7 +1261,7 @@ namespace aux { #ifndef TORRENT_DISABLE_LOGGING bool should_log() const override; - void session_log(char const* fmt, ...) const override TORRENT_FORMAT(2,3); + void session_log(char const* fmt, ...) const noexcept override TORRENT_FORMAT(2,3); #endif #ifndef TORRENT_DISABLE_EXTENSIONS @@ -1314,7 +1314,7 @@ namespace aux { , error_code const& ec, const std::string& str , seconds32 retry_interval) override; bool should_log() const override; - void debug_log(const char* fmt, ...) const override TORRENT_FORMAT(2,3); + void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3); session_interface& m_ses; private: // explicitly disallow assignment, to silence msvc warning diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index 798d5f974..c9711dbb3 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -286,7 +286,9 @@ namespace aux { , buffer_allocator_interface { disk_io_thread(io_service& ios, counters& cnt); +#if TORRENT_USE_ASSERTS ~disk_io_thread(); +#endif void set_settings(settings_pack const* sett); diff --git a/include/libtorrent/packet_pool.hpp b/include/libtorrent/packet_pool.hpp index aab9c6f87..4900db441 100644 --- a/include/libtorrent/packet_pool.hpp +++ b/include/libtorrent/packet_pool.hpp @@ -160,6 +160,16 @@ namespace libtorrent { // can handle common cases of packet size by 3 pools struct TORRENT_EXTRA_EXPORT packet_pool : private single_threaded { + // there's a bug in GCC where allocating these in + // member initializer expressions won't propagate exceptions. + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80683 + packet_pool() + : m_syn_slab(TORRENT_UTP_HEADER) + , m_mtu_floor_slab(mtu_floor_size) + , m_mtu_ceiling_slab(mtu_ceiling_size) + {} + packet_pool(packet_pool&&) = default; + packet_ptr acquire(int const allocate) { TORRENT_ASSERT(is_single_thread()); @@ -202,9 +212,9 @@ namespace libtorrent { } static int const mtu_floor_size = TORRENT_INET_MIN_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER; static int const mtu_ceiling_size = TORRENT_ETHERNET_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER; - packet_slab m_syn_slab{ TORRENT_UTP_HEADER }; - packet_slab m_mtu_floor_slab{ mtu_floor_size }; - packet_slab m_mtu_ceiling_slab{ mtu_ceiling_size }; + packet_slab m_syn_slab; + packet_slab m_mtu_floor_slab; + packet_slab m_mtu_ceiling_slab; }; } diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index c4dc8f829..4b154d7b6 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -526,9 +526,9 @@ namespace aux { #ifndef TORRENT_DISABLE_LOGGING bool should_log(peer_log_alert::direction_t direction) const override; void peer_log(peer_log_alert::direction_t direction - , char const* event, char const* fmt, ...) const override TORRENT_FORMAT(4,5); + , char const* event, char const* fmt, ...) const noexcept override TORRENT_FORMAT(4,5); void peer_log(peer_log_alert::direction_t direction - , char const* event) const; + , char const* event) const noexcept; time_point m_connect_time; time_point m_bitfield_time; diff --git a/include/libtorrent/peer_connection_interface.hpp b/include/libtorrent/peer_connection_interface.hpp index 03b692194..45b61681b 100644 --- a/include/libtorrent/peer_connection_interface.hpp +++ b/include/libtorrent/peer_connection_interface.hpp @@ -65,7 +65,7 @@ namespace libtorrent { #ifndef TORRENT_DISABLE_LOGGING virtual bool should_log(peer_log_alert::direction_t direction) const = 0; virtual void peer_log(peer_log_alert::direction_t direction - , char const* event, char const* fmt = "", ...) const TORRENT_FORMAT(4,5) = 0; + , char const* event, char const* fmt = "", ...) const noexcept TORRENT_FORMAT(4,5) = 0; #endif protected: ~peer_connection_interface() {} diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index eecb546f8..9af5ebc16 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -1023,7 +1023,7 @@ namespace libtorrent { // LOGGING #ifndef TORRENT_DISABLE_LOGGING bool should_log() const override; - void debug_log(const char* fmt, ...) const override TORRENT_FORMAT(2,3); + void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3); void log_to_all_peers(char const* message); time_point m_dht_start_time; diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 353eecf67..2f353bf24 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -249,7 +249,7 @@ namespace libtorrent { #ifndef TORRENT_DISABLE_LOGGING virtual bool should_log() const = 0; - virtual void debug_log(const char* fmt, ...) const TORRENT_FORMAT(2,3) = 0; + virtual void debug_log(const char* fmt, ...) const noexcept TORRENT_FORMAT(2,3) = 0; #endif }; diff --git a/simulation/Jamfile b/simulation/Jamfile index 96c4eba99..135dbfb25 100644 --- a/simulation/Jamfile +++ b/simulation/Jamfile @@ -51,8 +51,6 @@ alias libtorrent-sims : [ run test_fast_extensions.cpp ] [ run test_file_pool.cpp ] [ run test_save_resume.cpp ] + [ run test_error_handling.cpp ] ; -run test_error_handling.cpp ; -explicit test_error_handling ; - diff --git a/simulation/test_error_handling.cpp b/simulation/test_error_handling.cpp index a5661b87c..1538479f4 100644 --- a/simulation/test_error_handling.cpp +++ b/simulation/test_error_handling.cpp @@ -51,6 +51,10 @@ POSSIBILITY OF SUCH DAMAGE. using namespace sim; +#if defined _MSC_VER && _ITERATOR_DEBUG_LEVEL > 0 +// https://developercommunity.visualstudio.com/content/problem/140200/c-stl-stdvector-constructor-declared-with-noexcept.html +#error "msvc's standard library does not support bad_alloc with debug iterators. This test only works with debug iterators disabled on msvc. _ITERATOR_DEBUG_LEVEL=0" +#endif std::string make_ep_string(char const* address, bool const is_v6 , char const* port) @@ -105,7 +109,7 @@ void run_test(HandleAlerts const& on_alert, Test const& test) // only monitor alerts for session 0 (the downloader) print_alerts(*ses[0], [=](lt::session& ses, lt::alert const* a) { - if (auto ta = alert_cast(a)) + if (auto ta = alert_cast(a)) { ta->handle.connect_peer(lt::tcp::endpoint(peer1, 6881)); } @@ -149,6 +153,22 @@ void* operator new(std::size_t sz) { char stack[10000]; print_backtrace(stack, sizeof(stack), 40, nullptr); +#ifdef _MSC_VER + // this is a bit unfortunate. Some MSVC standard containers really don't move + // with noexcept, by actually allocating memory (i.e. it's not just a matter + // of accidentally missing noexcept specifiers). The heterogeneous queue used + // by the alert manager requires alerts to be noexcept move constructable and + // move assignable, which they claim to be, even though on MSVC some of them + // aren't. Things will improve in C++17 and it doesn't seem worth the trouble + // to make the heterogeneous queue support throwing moves, nor to replace all + // standard types with variants that can move noexcept. + if (std::strstr(stack, " libtorrent::entry::operator= ") != nullptr + || std::strstr(stack, " libtorrent::aux::noexcept_movable 0) break; } + + // if this fails, we need to raise the limit in the loop above + TEST_CHECK(g_alloc_counter > 0); + + // we don't want any part of the actual test framework to suffer from failed + // allocations, so bump the counter + g_alloc_counter = 1000000; } diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 82e72ac89..4b7eeb4ee 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -329,7 +329,6 @@ cached_piece_entry::~cached_piece_entry() { for (int i = 0; i < blocks_in_piece; ++i) { - TORRENT_ASSERT(blocks[i].buf == nullptr); TORRENT_ASSERT(!blocks[i].pending); TORRENT_ASSERT(blocks[i].refcount == 0); TORRENT_ASSERT(blocks[i].hashing_count == 0); diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index f3346df4c..27d62fa05 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -227,6 +227,9 @@ constexpr disk_job_flags_t disk_interface::cache_hit; TORRENT_ASSERT(storage); if (m_free_slots.empty()) { + // make sure there's always space in here to add another free slot. + // stopping a torrent should never fail because it needs to allocate memory + m_free_slots.reserve(m_torrents.size() + 1); storage_index_t const idx = m_torrents.end_index(); m_torrents.emplace_back(std::move(storage)); m_torrents.back()->set_storage_index(idx); @@ -251,21 +254,15 @@ constexpr disk_job_flags_t disk_interface::cache_hit; } } +#if TORRENT_USE_ASSERTS disk_io_thread::~disk_io_thread() { DLOG("destructing disk_io_thread\n"); -#if TORRENT_USE_ASSERTS - // by now, all pieces should have been evicted - auto pieces = m_disk_cache.all_pieces(); - TORRENT_ASSERT(pieces.first == pieces.second); -#endif - TORRENT_ASSERT(m_magic == 0x1337); -#if TORRENT_USE_ASSERTS m_magic = 0xdead; -#endif } +#endif void disk_io_thread::abort(bool const wait) { diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index e1c7f98cd..de8f87840 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -182,6 +182,11 @@ namespace libtorrent { , print_endpoint(local_ep).c_str()); } #endif + + // this counter should not be incremeneted until we know constructing this + // peer object can't fail anymore + if (m_connecting && t) t->inc_num_connecting(m_peer_info); + #if TORRENT_USE_ASSERTS piece_failed = false; m_in_constructor = false; @@ -372,8 +377,6 @@ namespace libtorrent { // if this is an incoming connection, we're done here if (!m_connecting) return; - if (m_connecting && t) t->inc_num_connecting(m_peer_info); - #ifndef TORRENT_DISABLE_LOGGING if (should_log(peer_log_alert::outgoing)) { @@ -529,14 +532,14 @@ namespace libtorrent { } void peer_connection::peer_log(peer_log_alert::direction_t direction - , char const* event) const + , char const* event) const noexcept { peer_log(direction, event, ""); } TORRENT_FORMAT(4,5) void peer_connection::peer_log(peer_log_alert::direction_t direction - , char const* event, char const* fmt, ...) const + , char const* event, char const* fmt, ...) const noexcept try { TORRENT_ASSERT(is_single_thread()); @@ -555,6 +558,7 @@ namespace libtorrent { va_end(v); } + catch (std::exception const&) {} #endif #ifndef TORRENT_DISABLE_EXTENSIONS @@ -797,8 +801,6 @@ namespace libtorrent { // INVARIANT_CHECK; TORRENT_ASSERT(!m_in_constructor); - TORRENT_ASSERT(m_disconnecting); - TORRENT_ASSERT(m_disconnect_started); TORRENT_ASSERT(!m_destructed); #if TORRENT_USE_ASSERTS m_destructed = true; @@ -836,7 +838,6 @@ namespace libtorrent { TORRENT_ASSERT(t || !m_connecting); // we should really have dealt with this already - TORRENT_ASSERT(!m_connecting); if (m_connecting) { m_counters.inc_stats_counter(counters::num_peers_half_open, -1); @@ -853,11 +854,6 @@ namespace libtorrent { #endif TORRENT_ASSERT(m_request_queue.empty()); TORRENT_ASSERT(m_download_queue.empty()); - -#if TORRENT_USE_ASSERTS - if (m_peer_info) - TORRENT_ASSERT(m_peer_info->connection == nullptr); -#endif } bool peer_connection::on_parole() const @@ -4385,7 +4381,7 @@ namespace libtorrent { m_queued_time_critical = 0; #if TORRENT_USE_INVARIANT_CHECKS - check_invariant(); + try { check_invariant(); } catch (std::exception const&) {} #endif t->remove_peer(self()); @@ -6326,10 +6322,6 @@ namespace libtorrent { TORRENT_ASSERT(m_request_queue.empty()); TORRENT_ASSERT(m_disconnect_started); } - else if (!m_in_constructor) - { - TORRENT_ASSERT(m_ses.has_peer(this)); - } TORRENT_ASSERT(m_outstanding_bytes >= 0); if (t && t->valid_metadata() && !m_disconnecting) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 9b12537e3..fa57fb505 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -882,12 +882,13 @@ namespace aux { session_log(" aborting all connections (%d)", int(m_connections.size())); #endif // abort all connections - // keep in mind that connections that are not associated with a torrent - // will remove its entry from m_connections immediately, which means we - // can't iterate over it here - auto conns = m_connections; - for (auto const& p : conns) + for (connection_map::iterator i = m_connections.begin(); + i != m_connections.end();) + { + peer_connection* p = (*i).get(); + ++i; p->disconnect(errors::stopping_torrent, operation_t::bittorrent); + } // close the listen sockets for (auto const& l : m_listen_sockets) @@ -4533,7 +4534,7 @@ namespace { } TORRENT_FORMAT(2,3) - void session_impl::session_log(char const* fmt, ...) const + void session_impl::session_log(char const* fmt, ...) const noexcept try { if (!m_alerts.should_post()) return; @@ -4542,6 +4543,7 @@ namespace { m_alerts.emplace_alert(fmt, v); va_end(v); } + catch (std::exception const&) {} #endif void session_impl::get_torrent_status(std::vector* ret @@ -7147,7 +7149,7 @@ namespace { return m_ses.alerts().should_post(); } - void tracker_logger::debug_log(const char* fmt, ...) const + void tracker_logger::debug_log(const char* fmt, ...) const noexcept try { if (!m_ses.alerts().should_post()) return; @@ -7156,5 +7158,6 @@ namespace { m_ses.alerts().emplace_alert(fmt, v); va_end(v); } + catch (std::exception const&) {} #endif // TORRENT_DISABLE_LOGGING }} diff --git a/src/torrent.cpp b/src/torrent.cpp index a9505d927..d56e2de77 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -4361,8 +4361,23 @@ namespace libtorrent { // the torrent object from there if (m_storage) { - m_ses.disk_thread().async_stop_torrent(m_storage - , std::bind(&torrent::on_torrent_aborted, shared_from_this())); + try { + m_ses.disk_thread().async_stop_torrent(m_storage + , std::bind(&torrent::on_torrent_aborted, shared_from_this())); + } + catch (std::exception const& e) + { + TORRENT_UNUSED(e); + m_storage.reset(); +#ifndef TORRENT_DISABLE_LOGGING + debug_log("Failed to flush disk cache: %s", e.what()); +#endif + // clients may rely on this alert to be posted, so it's probably a + // good idea to post it here, even though we failed + // TODO: 3 should this alert have an error code in it? + if (alerts().should_post()) + alerts().emplace_alert(get_handle()); + } } else { @@ -4401,6 +4416,10 @@ namespace libtorrent { // have been destructed if (m_peer_list) m_peer_list->clear(); m_connections.clear(); + m_peers_to_disconnect.clear(); + m_num_uploads = 0; + m_num_connecting = 0; + m_num_connecting_seeds = 0; } void torrent::set_super_seeding(bool on) @@ -6877,22 +6896,7 @@ namespace libtorrent { peers_erased(st.erased); m_peers_to_disconnect.reserve(m_connections.size() + 1); - - TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end()); - TORRENT_ASSERT(m_iterating_connections == 0); - sorted_insert(m_connections, p); - update_want_peers(); - update_want_tick(); - - if (p->peer_info_struct() && p->peer_info_struct()->seed) - { - TORRENT_ASSERT(m_num_seeds < 0xffff); - ++m_num_seeds; - } - -#ifndef TORRENT_DISABLE_LOGGING - debug_log("incoming peer (%d)", num_peers()); -#endif + m_connections.reserve(m_connections.size() + 1); #if TORRENT_USE_ASSERTS error_code ec; @@ -6956,13 +6960,33 @@ namespace libtorrent { if (m_share_mode) recalc_share_mode(); + // once we add the peer to our m_connections list, we can't throw an + // exception. That will end up violating an invariant between the session, + // torrent and peers + TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end()); + TORRENT_ASSERT(m_iterating_connections == 0); + sorted_insert(m_connections, p); + update_want_peers(); + update_want_tick(); + + if (p->peer_info_struct() && p->peer_info_struct()->seed) + { + TORRENT_ASSERT(m_num_seeds < 0xffff); + ++m_num_seeds; + } + #ifndef TORRENT_DISABLE_LOGGING - if (should_log()) + debug_log("incoming peer (%d)", num_peers()); +#endif + +#ifndef TORRENT_DISABLE_LOGGING + if (should_log()) try { debug_log("ATTACHED CONNECTION \"%s\" connections: %d limit: %d" , print_endpoint(p->remote()).c_str(), num_peers() , m_max_connections); } + catch (std::exception const&) {} #endif return true; @@ -7775,7 +7799,7 @@ namespace libtorrent { TORRENT_ASSERT(is_single_thread()); // this fires during disconnecting peers -// if (is_paused()) TORRENT_ASSERT(num_peers() == 0 || m_graceful_pause_mode); + if (is_paused()) TORRENT_ASSERT(num_peers() == 0 || m_graceful_pause_mode); int seeds = 0; int num_uploads = 0; @@ -7784,10 +7808,6 @@ namespace libtorrent { std::map num_requests; for (peer_connection const* peer : *this) { -#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS - // make sure this peer is not a dangling pointer - TORRENT_ASSERT(m_ses.has_peer(peer)); -#endif peer_connection const& p = *peer; if (p.is_connecting()) ++num_connecting; @@ -7813,16 +7833,19 @@ namespace libtorrent { if (associated_torrent != this && associated_torrent != nullptr) TORRENT_ASSERT_FAIL(); } - TORRENT_ASSERT(num_uploads == int(m_num_uploads)); - TORRENT_ASSERT(seeds == int(m_num_seeds)); - TORRENT_ASSERT(num_connecting == int(m_num_connecting)); - TORRENT_ASSERT(num_connecting_seeds == int(m_num_connecting_seeds)); - TORRENT_ASSERT(int(m_num_uploads) <= num_peers()); - TORRENT_ASSERT(int(m_num_seeds) <= num_peers()); - TORRENT_ASSERT(int(m_num_connecting) <= num_peers()); - TORRENT_ASSERT(int(m_num_connecting_seeds) <= num_peers()); - TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds)); - TORRENT_ASSERT(int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds) <= num_peers()); + TORRENT_ASSERT_VAL(num_uploads == int(m_num_uploads), int(m_num_uploads) - num_uploads); + TORRENT_ASSERT_VAL(seeds == int(m_num_seeds), int(m_num_seeds) - seeds); + TORRENT_ASSERT_VAL(num_connecting == int(m_num_connecting), int(m_num_connecting) - num_connecting); + TORRENT_ASSERT_VAL(num_connecting_seeds == int(m_num_connecting_seeds) + , int(m_num_connecting_seeds) - num_connecting_seeds); + TORRENT_ASSERT_VAL(int(m_num_uploads) <= num_peers(), m_num_uploads - num_peers()); + TORRENT_ASSERT_VAL(int(m_num_seeds) <= num_peers(), m_num_seeds - num_peers()); + TORRENT_ASSERT_VAL(int(m_num_connecting) <= num_peers(), int(m_num_connecting) - num_peers()); + TORRENT_ASSERT_VAL(int(m_num_connecting_seeds) <= num_peers(), int(m_num_connecting_seeds) - num_peers()); + TORRENT_ASSERT_VAL(int(m_num_connecting) + int(m_num_seeds) >= int(m_num_connecting_seeds) + , int(m_num_connecting_seeds) - (int(m_num_connecting) + int(m_num_seeds))); + TORRENT_ASSERT_VAL(int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds) <= num_peers() + , num_peers() - (int(m_num_connecting) + int(m_num_seeds) - int(m_num_connecting_seeds))); if (has_picker()) { @@ -10979,7 +11002,7 @@ namespace { } TORRENT_FORMAT(2,3) - void torrent::debug_log(char const* fmt, ...) const + void torrent::debug_log(char const* fmt, ...) const noexcept try { if (!alerts().should_post()) return; @@ -10989,6 +11012,7 @@ namespace { const_cast(this)->get_handle(), fmt, v); va_end(v); } + catch (std::exception const&) {} #endif } diff --git a/test/test_peer_list.cpp b/test/test_peer_list.cpp index 210b874aa..322a23bed 100644 --- a/test/test_peer_list.cpp +++ b/test/test_peer_list.cpp @@ -70,11 +70,11 @@ struct mock_peer_connection virtual ~mock_peer_connection() = default; #if !defined TORRENT_DISABLE_LOGGING - bool should_log(peer_log_alert::direction_t) const override + bool should_log(peer_log_alert::direction_t) const noexcept override { return true; } void peer_log(peer_log_alert::direction_t dir, char const* event - , char const* fmt, ...) const override + , char const* fmt, ...) const noexcept override { va_list v; va_start(v, fmt);