From 9baa280b52c93c1f2cca02644982623281f8db8a Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 18 Jul 2010 19:28:22 +0000 Subject: [PATCH] added asserts to catch broken peer allocations and frees as well as disk buffer corruption --- examples/client_test.cpp | 2 ++ include/libtorrent/policy.hpp | 3 +++ src/allocator.cpp | 44 +++++++++++++++++++++++++++++++++++ src/policy.cpp | 30 ++++++++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 6d64077de..90c4b6222 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -775,6 +775,7 @@ int main(int argc, char* argv[]) " -O Disallow disk job reordering\n" " -P Use the specified SOCKS5 proxy\n" " -H Don't start DHT\n" + " -W Set the max number of peers to keep in the peer list\n" " " "\n\n" "TORRENT is a path to a .torrent file\n" @@ -895,6 +896,7 @@ int main(int argc, char* argv[]) case 't': poll_interval = atoi(arg); break; case 'F': refresh_delay = atoi(arg); break; case 'H': start_dht = false; --i; break; + case 'W': settings.max_peerlist_size = atoi(arg); break; case 'x': { FILE* filter = fopen(arg, "r"); diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 9aca316ed..b3ce149d7 100644 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -310,6 +310,9 @@ namespace libtorrent // this is set to true when this peer as been // pinged by the DHT bool added_to_dht:1; +#endif +#ifdef TORRENT_DEBUG + bool in_use:1; #endif }; diff --git a/src/allocator.cpp b/src/allocator.cpp index 8ca8d7046..aaeca05ad 100644 --- a/src/allocator.cpp +++ b/src/allocator.cpp @@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/allocator.hpp" #include "libtorrent/config.hpp" +#include "libtorrent/assert.hpp" #ifdef TORRENT_WINDOWS #include @@ -47,6 +48,18 @@ POSSIBILITY OF SUCH DAMAGE. #include // memalign #endif +#ifdef TORRENT_DEBUG_BUFFERS +#include +#include "libtorrent/size_type.hpp" + +struct alloc_header +{ + libtorrent::size_type size; + int magic; +}; + +#endif + namespace libtorrent { int page_size() @@ -71,6 +84,21 @@ namespace libtorrent char* page_aligned_allocator::malloc(const size_type bytes) { +#ifdef TORRENT_DEBUG_BUFFERS + int page = page_size(); + char* ret = (char*)valloc(bytes + 2 * page); + // make the two surrounding pages non-readable and -writable + TORRENT_ASSERT((bytes & (page-1)) == 0); + alloc_header* h = (alloc_header*)ret; + h->size = bytes; + h->magic = 0x1337; + mprotect(ret, page, PROT_READ); + mprotect(ret + page + bytes, page, PROT_READ); +// fprintf(stderr, "malloc: %p head: %p tail: %p size: %d\n", ret + page, ret, ret + page + bytes, int(bytes)); + + return ret + page; +#endif + #if TORRENT_USE_POSIX_MEMALIGN void* ret; if (posix_memalign(&ret, page_size(), bytes) != 0) ret = 0; @@ -92,6 +120,22 @@ namespace libtorrent void page_aligned_allocator::free(char* const block) { + +#ifdef TORRENT_DEBUG_BUFFERS + int page = page_size(); + // make the two surrounding pages non-readable and -writable + mprotect(block - page, page, PROT_READ | PROT_WRITE); + alloc_header* h = (alloc_header*)(block - page); + TORRENT_ASSERT((h->size & (page-1)) == 0); + TORRENT_ASSERT(h->magic == 0x1337); + mprotect(block + h->size, page, PROT_READ | PROT_WRITE); +// fprintf(stderr, "free: %p head: %p tail: %p size: %d\n", block, block - page, block + h->size, int(h->size)); + h->magic = 0; + + ::free(block - page); + return; +#endif + #ifdef TORRENT_WINDOWS VirtualFree(block, 0, MEM_RELEASE); #elif defined TORRENT_BEOS diff --git a/src/policy.cpp b/src/policy.cpp index 99f015544..ee77b5790 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -385,6 +385,11 @@ namespace libtorrent if (m_round_robin > i - m_peers.begin()) --m_round_robin; if (m_round_robin >= m_peers.size()) m_round_robin = 0; +#ifdef TORRENT_DEBUG + TORRENT_ASSERT((*i)->in_use); + (*i)->in_use = false; +#endif + #if TORRENT_USE_IPV6 if ((*i)->is_v6_addr) { @@ -465,6 +470,7 @@ namespace libtorrent { if (erase_candidate > current) --erase_candidate; TORRENT_ASSERT(current >= 0 && current < m_peers.size()); + --round_robin; erase_peer(m_peers.begin() + current); } else @@ -601,6 +607,7 @@ namespace libtorrent { if (erase_candidate > current) --erase_candidate; if (candidate > current) --candidate; + --m_round_robin; erase_peer(m_peers.begin() + current); } else @@ -805,6 +812,9 @@ namespace libtorrent #endif (peer*)m_torrent->session().m_ipv4_peer_pool.malloc(); if (p == 0) return false; + +// TORRENT_ASSERT(p->in_use == false); + #if TORRENT_USE_IPV6 if (is_v6) m_torrent->session().m_ipv6_peer_pool.set_next_size(500); @@ -819,6 +829,10 @@ namespace libtorrent #endif new (p) ipv4_peer(c.remote(), false, 0); +#ifdef TORRENT_DEBUG + p->in_use = true; +#endif + iter = m_peers.insert(iter, p); if (m_round_robin >= iter - m_peers.begin()) ++m_round_robin; @@ -1085,8 +1099,17 @@ namespace libtorrent if (p == 0) return 0; m_torrent->session().m_i2p_peer_pool.set_next_size(500); new (p) i2p_peer(destination, true, src); + +#ifdef TORRENT_DEBUG + p->in_use = true; +#endif + if (!insert_peer(p, iter, flags)) { +#ifdef TORRENT_DEBUG + p->in_use = false; +#endif + m_torrent->session().m_i2p_peer_pool.free((i2p_peer*)p); return 0; } @@ -1188,8 +1211,15 @@ namespace libtorrent #endif new (p) ipv4_peer(remote, true, src); +#ifdef TORRENT_DEBUG + p->in_use = true; +#endif + if (!insert_peer(p, iter, flags)) { +#ifdef TORRENT_DEBUG + p->in_use = false; +#endif #if TORRENT_USE_IPV6 if (is_v6) m_torrent->session().m_ipv6_peer_pool.free((ipv6_peer*)p); else