improve messaging of assert caused by precondition violation

This commit is contained in:
Arvid Norberg 2014-03-23 07:40:43 +00:00
parent 45f3fa4696
commit 682ceff21b
6 changed files with 61 additions and 42 deletions

View File

@ -53,23 +53,32 @@ extern char const* libtorrent_assert_log;
#endif
TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file
, char const* function, char const* val);
, char const* function, char const* val, int kind = 0);
#define TORRENT_ASSERT_PRECOND(x) \
do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, "", 1); } while (false)
#define TORRENT_ASSERT(x) \
do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, "", 0); } while (false)
#define TORRENT_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, 0); } while (false)
#if TORRENT_USE_IOSTREAM
#define TORRENT_ASSERT_VAL(x, y) do { if (x) {} else { std::stringstream __s__; __s__ << #y ": " << y; assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, __s__.str().c_str()); } } while (false)
#define TORRENT_ASSERT_VAL(x, y) \
do { if (x) {} else { std::stringstream __s__; __s__ << #y ": " << y; \
assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__, __s__.str().c_str(), 0); } } while (false)
#else
#define TORRENT_ASSERT_VAL(x, y) TORRENT_ASSERT(x)
#endif
#else
#include <cassert>
#define TORRENT_ASSERT_PRECOND(x) assert(x)
#define TORRENT_ASSERT(x) assert(x)
#define TORRENT_ASSERT_VAL(x, y) assert(x)
#endif
#else // TORRENT_USE_ASSERTS
#define TORRENT_ASSERT_PRECOND(a) do {} while(false)
#define TORRENT_ASSERT(a) do {} while(false)
#define TORRENT_ASSERT_VAL(a, b) do {} while(false)

View File

@ -215,7 +215,7 @@ boost::detail::atomic_count assert_counter(0);
#endif
TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
, char const* function, char const* value)
, char const* function, char const* value, int kind)
{
#if TORRENT_PRODUCTION_ASSERTS
// no need to flood the assert log with infinite number of asserts
@ -231,11 +231,20 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
stack[0] = '\0';
print_backtrace(stack, sizeof(stack), 0);
fprintf(out, "assertion failed. Please file a bugreport at "
char const* message = "assertion failed. Please file a bugreport at "
"http://code.google.com/p/libtorrent/issues\n"
"Please include the following information:\n\n"
"version: " LIBTORRENT_VERSION "\n"
"%s\n"
LIBTORRENT_REVISION "\n";
switch (kind)
{
case 1:
message = "A precondition of a libtorrent function has been violated.\n"
"This indicates a bug in the client application using libtorrent\n";
}
fprintf(out, "%s\n"
"file: '%s'\n"
"line: %d\n"
"function: %s\n"
@ -243,7 +252,7 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
"%s%s\n"
"stack:\n"
"%s\n"
, LIBTORRENT_REVISION, file, line, function, expr
, message, file, line, function, expr
, value ? value : "", value ? "\n" : ""
, stack);
@ -260,7 +269,8 @@ TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
#else
TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file, char const* function) {}
TORRENT_EXPORT void assert_fail(char const* expr, int line, char const* file
, char const* function, char const* value, int kind) {}
#endif

View File

@ -55,7 +55,7 @@ namespace libtorrent
int file_storage::piece_size(int index) const
{
TORRENT_ASSERT(index >= 0 && index < num_pieces());
TORRENT_ASSERT_PRECOND(index >= 0 && index < num_pieces());
if (index == num_pieces()-1)
{
size_type size_except_last = num_pieces() - 1;
@ -213,7 +213,7 @@ namespace libtorrent
void file_storage::rename_file(int index, std::wstring const& new_filename)
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
std::string utf8;
wchar_utf8(new_filename, utf8);
m_files[index].set_name(utf8.c_str());
@ -232,14 +232,14 @@ namespace libtorrent
void file_storage::rename_file(int index, std::string const& new_filename)
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
m_files[index].set_name(new_filename.c_str());
update_path_index(m_files[index]);
}
void file_storage::rename_file_borrow(int index, char const* new_filename, int len)
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
m_files[index].set_name(new_filename, true, len);
}
@ -303,7 +303,7 @@ namespace libtorrent
std::vector<file_slice> file_storage::map_block(int piece, size_type offset
, int size) const
{
TORRENT_ASSERT(num_files() > 0);
TORRENT_ASSERT_PRECOND(num_files() > 0);
std::vector<file_slice> ret;
if (m_files.empty()) return ret;
@ -311,7 +311,7 @@ namespace libtorrent
// find the file iterator and file offset
internal_file_entry target;
target.offset = piece * (size_type)m_piece_length + offset;
TORRENT_ASSERT(target.offset + size <= m_total_size);
TORRENT_ASSERT_PRECOND(target.offset + size <= m_total_size);
TORRENT_ASSERT(!compare_file_offset(target, m_files.front()));
std::vector<internal_file_entry>::const_iterator file_iter = std::upper_bound(
@ -343,7 +343,7 @@ namespace libtorrent
file_entry file_storage::at(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
file_entry ret;
internal_file_entry const& ife = m_files[index];
ret.path = file_path(index);
@ -364,8 +364,8 @@ namespace libtorrent
peer_request file_storage::map_file(int file_index, size_type file_offset
, int size) const
{
TORRENT_ASSERT(file_index < num_files());
TORRENT_ASSERT(file_index >= 0);
TORRENT_ASSERT_PRECOND(file_index < num_files());
TORRENT_ASSERT_PRECOND(file_index >= 0);
peer_request ret;
if (file_index < 0 || file_index >= num_files())
@ -398,8 +398,8 @@ namespace libtorrent
void file_storage::add_file(std::string const& file, size_type size, int flags
, std::time_t mtime, std::string const& symlink_path)
{
TORRENT_ASSERT(!is_complete(file));
TORRENT_ASSERT(size >= 0);
TORRENT_ASSERT_PRECOND(!is_complete(file));
TORRENT_ASSERT_PRECOND(size >= 0);
if (size < 0) size = 0;
if (!has_parent_path(file))
{
@ -407,7 +407,7 @@ namespace libtorrent
// path to the file (branch_path), which means that
// all the other files need to be in the same top
// directory as the first file.
TORRENT_ASSERT(m_files.empty());
TORRENT_ASSERT_PRECOND(m_files.empty());
m_name = file;
}
else
@ -415,7 +415,7 @@ namespace libtorrent
if (m_files.empty())
m_name = split_path(file).c_str();
}
TORRENT_ASSERT(m_name == split_path(file).c_str());
TORRENT_ASSERT_PRECOND(m_name == split_path(file).c_str());
m_files.push_back(internal_file_entry());
internal_file_entry& e = m_files.back();
e.set_name(file.c_str());
@ -442,14 +442,14 @@ namespace libtorrent
void file_storage::add_file(file_entry const& ent, char const* filehash)
{
TORRENT_ASSERT(ent.size >= 0);
TORRENT_ASSERT_PRECOND(ent.size >= 0);
if (!has_parent_path(ent.path))
{
// you have already added at least one file with a
// path to the file (branch_path), which means that
// all the other files need to be in the same top
// directory as the first file.
TORRENT_ASSERT(m_files.empty());
TORRENT_ASSERT_PRECOND(m_files.empty());
m_name = ent.path;
}
else
@ -490,7 +490,7 @@ namespace libtorrent
std::string const& file_storage::symlink(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
internal_file_entry const& fe = m_files[index];
TORRENT_ASSERT(fe.symlink_index < int(m_symlinks.size()));
return m_symlinks[fe.symlink_index];
@ -504,7 +504,7 @@ namespace libtorrent
void file_storage::set_file_base(int index, size_type off)
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
if (int(m_file_base.size()) <= index) m_file_base.resize(index + 1, 0);
m_file_base[index] = off;
}
@ -517,7 +517,7 @@ namespace libtorrent
std::string file_storage::file_path(int index, std::string const& save_path) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
internal_file_entry const& fe = m_files[index];
// -2 means this is an absolute path filename
@ -539,26 +539,26 @@ namespace libtorrent
std::string file_storage::file_name(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
internal_file_entry const& fe = m_files[index];
return fe.filename();
}
size_type file_storage::file_size(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
return m_files[index].size;
}
bool file_storage::pad_file_at(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
return m_files[index].pad_file;
}
size_type file_storage::file_offset(int index) const
{
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
return m_files[index].offset;
}
@ -581,7 +581,7 @@ namespace libtorrent
std::string const& file_storage::symlink(internal_file_entry const& fe) const
{
TORRENT_ASSERT(fe.symlink_index < int(m_symlinks.size()));
TORRENT_ASSERT_PRECOND(fe.symlink_index < int(m_symlinks.size()));
return m_symlinks[fe.symlink_index];
}
@ -595,14 +595,14 @@ namespace libtorrent
int file_storage::file_index(internal_file_entry const& fe) const
{
int index = &fe - &m_files[0];
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
return index;
}
void file_storage::set_file_base(internal_file_entry const& fe, size_type off)
{
int index = &fe - &m_files[0];
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
if (int(m_file_base.size()) <= index) m_file_base.resize(index + 1, 0);
m_file_base[index] = off;
}

View File

@ -476,7 +476,7 @@ namespace libtorrent
feed_handle session::add_feed(feed_settings const& feed)
{
// if you have auto-download enabled, you must specify a download directory!
TORRENT_ASSERT(!feed.auto_download || !feed.add_args.save_path.empty());
TORRENT_ASSERT_PRECOND(!feed.auto_download || !feed.add_args.save_path.empty());
TORRENT_SYNC_CALL_RET1(feed_handle, add_feed, feed);
return r;
}

View File

@ -1896,7 +1896,7 @@ namespace aux {
// If you hit this assert, you're trying to set your cache to be
// volatile and to suggest pieces out of it (or to make the cache
// explicit) at the same time this is a bad configuration, don't do it
TORRENT_ASSERT(false);
TORRENT_ASSERT_PRECOND(false);
m_settings.volatile_read_cache = false;
}

View File

@ -282,7 +282,7 @@ namespace libtorrent
void torrent_handle::set_max_uploads(int max_uploads) const
{
TORRENT_ASSERT(max_uploads >= 2 || max_uploads == -1);
TORRENT_ASSERT_PRECOND(max_uploads >= 2 || max_uploads == -1);
TORRENT_ASYNC_CALL2(set_max_uploads, max_uploads, true);
}
@ -294,13 +294,13 @@ namespace libtorrent
void torrent_handle::set_max_connections(int max_connections) const
{
TORRENT_ASSERT(max_connections >= 2 || max_connections == -1);
TORRENT_ASSERT_PRECOND(max_connections >= 2 || max_connections == -1);
TORRENT_ASYNC_CALL2(set_max_connections, max_connections, true);
}
void torrent_handle::set_upload_limit(int limit) const
{
TORRENT_ASSERT(limit >= -1);
TORRENT_ASSERT_PRECOND(limit >= -1);
TORRENT_ASYNC_CALL2(set_upload_limit, limit, true);
}
@ -312,7 +312,7 @@ namespace libtorrent
void torrent_handle::set_download_limit(int limit) const
{
TORRENT_ASSERT(limit >= -1);
TORRENT_ASSERT_PRECOND(limit >= -1);
TORRENT_ASYNC_CALL2(set_download_limit, limit, true);
}
@ -568,20 +568,20 @@ namespace libtorrent
void torrent_handle::set_peer_upload_limit(tcp::endpoint ip, int limit) const
{
TORRENT_ASSERT(limit >= -1);
TORRENT_ASSERT_PRECOND(limit >= -1);
TORRENT_ASYNC_CALL2(set_peer_upload_limit, ip, limit);
}
void torrent_handle::set_peer_download_limit(tcp::endpoint ip, int limit) const
{
TORRENT_ASSERT(limit >= -1);
TORRENT_ASSERT_PRECOND(limit >= -1);
TORRENT_ASYNC_CALL2(set_peer_download_limit, ip, limit);
}
void torrent_handle::set_ratio(float ratio) const
{
TORRENT_ASSERT(ratio >= 0.f);
TORRENT_ASSERT_PRECOND(ratio >= 0.f);
if (ratio < 1.f && ratio > 0.f)
ratio = 1.f;
TORRENT_ASYNC_CALL1(set_ratio, ratio);