2007-08-20 06:58:56 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (c) 2007, Arvid Norberg
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2008-12-19 07:12:55 +01:00
|
|
|
#ifdef TORRENT_DEBUG
|
|
|
|
|
2008-12-19 10:17:55 +01:00
|
|
|
#ifdef __APPLE__
|
|
|
|
#include <AvailabilityMacros.h>
|
|
|
|
#endif
|
|
|
|
|
2007-12-27 07:15:52 +01:00
|
|
|
#include <string>
|
2008-04-29 23:46:32 +02:00
|
|
|
#include <cstring>
|
2007-12-27 07:15:52 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2009-10-20 18:44:11 +02:00
|
|
|
// uClibc++ doesn't have cxxabi.h
|
2009-11-28 23:41:21 +01:00
|
|
|
#if defined __GNUC__ && __GNUC__ >= 3 \
|
|
|
|
&& !defined __UCLIBCXX_MAJOR__
|
2009-10-20 18:44:11 +02:00
|
|
|
|
|
|
|
#include <cxxabi.h>
|
|
|
|
|
2007-12-27 07:15:52 +01:00
|
|
|
std::string demangle(char const* name)
|
|
|
|
{
|
|
|
|
// in case this string comes
|
2008-12-19 07:12:55 +01:00
|
|
|
// this is needed on linux
|
2007-12-27 07:15:52 +01:00
|
|
|
char const* start = strchr(name, '(');
|
2008-12-19 07:12:55 +01:00
|
|
|
if (start != 0)
|
|
|
|
{
|
|
|
|
++start;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// this is needed on macos x
|
|
|
|
start = strstr(name, "0x");
|
|
|
|
if (start != 0)
|
|
|
|
{
|
|
|
|
start = strchr(start, ' ');
|
|
|
|
if (start != 0) ++start;
|
|
|
|
else start = name;
|
|
|
|
}
|
|
|
|
else start = name;
|
|
|
|
}
|
|
|
|
|
2007-12-27 07:15:52 +01:00
|
|
|
char const* end = strchr(start, '+');
|
2008-12-19 07:12:55 +01:00
|
|
|
if (end) while (*(end-1) == ' ') --end;
|
2007-12-27 07:15:52 +01:00
|
|
|
|
|
|
|
std::string in;
|
|
|
|
if (end == 0) in.assign(start);
|
|
|
|
else in.assign(start, end);
|
|
|
|
|
|
|
|
size_t len;
|
|
|
|
int status;
|
|
|
|
char* unmangled = ::abi::__cxa_demangle(in.c_str(), 0, &len, &status);
|
|
|
|
if (unmangled == 0) return in;
|
|
|
|
std::string ret(unmangled);
|
|
|
|
free(unmangled);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-10-20 18:44:11 +02:00
|
|
|
#else
|
|
|
|
std::string demangle(char const* name) { return name; }
|
2007-12-27 07:15:52 +01:00
|
|
|
#endif
|
|
|
|
|
2007-09-01 06:08:39 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2007-09-17 04:32:51 +02:00
|
|
|
#include <signal.h>
|
2009-01-14 09:41:14 +01:00
|
|
|
#include "libtorrent/version.hpp"
|
2008-12-19 07:12:55 +01:00
|
|
|
|
2008-12-19 10:17:55 +01:00
|
|
|
// execinfo.h is available in the MacOS X 10.5 SDK.
|
|
|
|
#if (defined __linux__ || (defined __APPLE__ && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050))
|
2007-08-20 06:58:56 +02:00
|
|
|
#include <execinfo.h>
|
2008-12-19 07:12:55 +01:00
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
void print_backtrace(FILE* out, char const* label)
|
2008-12-19 07:12:55 +01:00
|
|
|
{
|
|
|
|
void* stack[50];
|
|
|
|
int size = backtrace(stack, 50);
|
|
|
|
char** symbols = backtrace_symbols(stack, size);
|
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
fprintf(out, "%s\n", label);
|
2008-12-19 07:12:55 +01:00
|
|
|
for (int i = 1; i < size; ++i)
|
|
|
|
{
|
2010-05-06 04:18:08 +02:00
|
|
|
fprintf(out, "%d: %s\n", i, demangle(symbols[i]).c_str());
|
2008-12-19 07:12:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
free(symbols);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
void print_backtrace(FILE* out, char const* label) {}
|
2008-12-19 07:12:55 +01:00
|
|
|
|
2007-09-17 04:32:51 +02:00
|
|
|
#endif
|
2007-08-20 06:58:56 +02:00
|
|
|
|
2007-09-01 06:08:39 +02:00
|
|
|
void assert_fail(char const* expr, int line, char const* file, char const* function)
|
2007-08-20 06:58:56 +02:00
|
|
|
{
|
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
#if TORRENT_PRODUCTION_ASSERTS
|
|
|
|
FILE* out = fopen("asserts.log", "a+");
|
|
|
|
if (out == 0) out = stderr;
|
|
|
|
#else
|
|
|
|
FILE* out = stderr;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fprintf(out, "assertion failed. Please file a bugreport at "
|
2007-08-20 06:58:56 +02:00
|
|
|
"http://code.rasterbar.com/libtorrent/newticket\n"
|
|
|
|
"Please include the following information:\n\n"
|
2009-01-14 09:41:14 +01:00
|
|
|
"version: " LIBTORRENT_VERSION "\n"
|
2009-01-15 05:45:28 +01:00
|
|
|
"%s\n"
|
2007-08-20 06:58:56 +02:00
|
|
|
"file: '%s'\n"
|
|
|
|
"line: %d\n"
|
2007-09-01 06:08:39 +02:00
|
|
|
"function: %s\n"
|
2009-01-14 09:41:14 +01:00
|
|
|
"expression: %s\n", LIBTORRENT_REVISION, file, line, function, expr);
|
2007-08-20 06:58:56 +02:00
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
print_backtrace(out, "stack:");
|
2007-08-20 06:58:56 +02:00
|
|
|
|
2010-05-06 04:18:08 +02:00
|
|
|
// if production asserts are defined, don't abort, just print the error
|
|
|
|
#if TORRENT_PRODUCTION_ASSERTS
|
|
|
|
if (out != stderr) fclose(out);
|
|
|
|
#else
|
2007-09-17 04:32:51 +02:00
|
|
|
// send SIGINT to the current process
|
|
|
|
// to break into the debugger
|
|
|
|
raise(SIGINT);
|
|
|
|
abort();
|
2010-05-06 04:18:08 +02:00
|
|
|
#endif
|
2007-08-20 06:58:56 +02:00
|
|
|
}
|
|
|
|
|
2007-10-05 02:30:00 +02:00
|
|
|
#else
|
|
|
|
|
|
|
|
void assert_fail(char const* expr, int line, char const* file, char const* function) {}
|
|
|
|
|
2007-08-20 06:58:56 +02:00
|
|
|
#endif
|
|
|
|
|