added asserts to catch broken peer allocations and frees as well as disk buffer corruption

This commit is contained in:
Arvid Norberg 2010-07-18 19:28:22 +00:00
parent f93960884c
commit 9baa280b52
4 changed files with 79 additions and 0 deletions

View File

@ -775,6 +775,7 @@ int main(int argc, char* argv[])
" -O Disallow disk job reordering\n"
" -P <host:port> Use the specified SOCKS5 proxy\n"
" -H Don't start DHT\n"
" -W <num peers> 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");

View File

@ -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
};

View File

@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/allocator.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#ifdef TORRENT_WINDOWS
#include <Windows.h>
@ -47,6 +48,18 @@ POSSIBILITY OF SUCH DAMAGE.
#include <malloc.h> // memalign
#endif
#ifdef TORRENT_DEBUG_BUFFERS
#include <sys/mman.h>
#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

View File

@ -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