forked from premiere/premiere-libtorrent
support backtraces on windows
This commit is contained in:
parent
6e9ef9edab
commit
f13a91d8a8
15
Jamfile
15
Jamfile
|
@ -64,6 +64,14 @@ rule linking ( properties * )
|
|||
|
||||
}
|
||||
|
||||
if <target-os>windows in $(properties)
|
||||
&& ( <asserts>on in $(properties)
|
||||
|| <variant>debug in $(properties)
|
||||
|| <asio-debugging>on in $(properties) )
|
||||
{
|
||||
result += <library>dbghelp ;
|
||||
}
|
||||
|
||||
# gcrypt libraries, if enabled
|
||||
if <encryption>gcrypt in $(properties) || <encryption>openssl in $(properties)
|
||||
{
|
||||
|
@ -187,10 +195,8 @@ rule building ( properties * )
|
|||
{
|
||||
local result ;
|
||||
|
||||
if ( <target-os>linux in $(properties)
|
||||
|| <target-os>darwin in $(properties) )
|
||||
&& ( <toolset>gcc in $(properties)
|
||||
|| <toolset>darwin in $(properties) )
|
||||
if ( <variant>debug in $(properties)
|
||||
|| <asserts>on in $(properties) )
|
||||
{
|
||||
result += <source>src/assert.cpp ;
|
||||
}
|
||||
|
@ -345,6 +351,7 @@ lib advapi32 : : <name>Advapi32 ;
|
|||
lib user32 : : <name>User32 ;
|
||||
lib shell32 : : <name>shell32 ;
|
||||
lib gdi32 : : <name>gdi32 ;
|
||||
lib dbghelp : : <name>dbghelp ;
|
||||
|
||||
# required for networking on beos
|
||||
lib netkit : : <name>net <search>/boot/system/lib <link>shared ;
|
||||
|
|
|
@ -46,9 +46,8 @@ extern char const* libtorrent_assert_log;
|
|||
|
||||
#include <string>
|
||||
|
||||
#ifdef __GNUC__
|
||||
std::string demangle(char const* name);
|
||||
#endif
|
||||
void print_backtrace(char* out, int len);
|
||||
|
||||
#if (defined __linux__ || defined __MACH__) && defined __GNUC__ && !TORRENT_USE_SYSTEM_ASSERT
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/thread.hpp"
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <map>
|
||||
|
||||
std::string demangle(char const* name);
|
||||
|
@ -62,18 +61,9 @@ namespace libtorrent
|
|||
async_t& a = _async_ops[name];
|
||||
if (a.stack.empty())
|
||||
{
|
||||
void* stack[50];
|
||||
int size = backtrace(stack, 50);
|
||||
char** symbols = backtrace_symbols(stack, size);
|
||||
|
||||
for (int i = 1; i < size; ++i)
|
||||
{
|
||||
char str[200];
|
||||
snprintf(str, sizeof(str), "%d: %s\n", i, demangle(symbols[i]).c_str());
|
||||
a.stack += str;
|
||||
}
|
||||
|
||||
free(symbols);
|
||||
char stack_text[10000];
|
||||
print_backtrace(stack_text, sizeof(stack_text));
|
||||
a.stack = stack_text;
|
||||
}
|
||||
++a.refs;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,21 @@ std::string demangle(char const* name)
|
|||
free(unmangled);
|
||||
return ret;
|
||||
}
|
||||
#elif defined WIN32
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 // XP
|
||||
|
||||
#include "windows.h"
|
||||
#include "dbghelp.h"
|
||||
|
||||
std::string demangle(char const* name)
|
||||
{
|
||||
char demangled_name[256];
|
||||
if (UnDecorateSymbolName(name, demangled_name, sizeof(demangled_name), UNDNAME_NO_THROW_SIGNATURES) == 0)
|
||||
demangled_name[0] = 0;
|
||||
return demangled_name;
|
||||
}
|
||||
|
||||
#else
|
||||
std::string demangle(char const* name) { return name; }
|
||||
|
@ -114,6 +129,69 @@ void print_backtrace(char* out, int len)
|
|||
|
||||
free(symbols);
|
||||
}
|
||||
|
||||
#elif defined WIN32
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 // XP
|
||||
|
||||
#include "windows.h"
|
||||
#include "libtorrent/utf8.hpp"
|
||||
|
||||
#include "winbase.h"
|
||||
#include "dbghelp.h"
|
||||
|
||||
void print_backtrace(char* out, int len)
|
||||
{
|
||||
typedef USHORT (*RtlCaptureStackBackTrace_t)(
|
||||
__in ULONG FramesToSkip,
|
||||
__in ULONG FramesToCapture,
|
||||
__out PVOID *BackTrace,
|
||||
__out_opt PULONG BackTraceHash);
|
||||
|
||||
static RtlCaptureStackBackTrace_t RtlCaptureStackBackTrace = 0;
|
||||
|
||||
if (RtlCaptureStackBackTrace == 0)
|
||||
{
|
||||
// we don't actually have to free this library, everyone has it loaded
|
||||
HMODULE lib = LoadLibrary(TEXT("kernel32.dll"));
|
||||
RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_t)GetProcAddress(lib, "RtlCaptureStackBackTrace");
|
||||
if (RtlCaptureStackBackTrace == 0)
|
||||
{
|
||||
out[0] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
void* stack[50];
|
||||
int size = CaptureStackBackTrace(0, 50, stack, 0);
|
||||
|
||||
SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR), 1);
|
||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
|
||||
HANDLE p = GetCurrentProcess();
|
||||
static bool sym_initialized = false;
|
||||
if (!sym_initialized)
|
||||
{
|
||||
sym_initialized = true;
|
||||
SymInitialize(p, NULL, true);
|
||||
}
|
||||
for (i = 0; i < size && len > 0; ++i)
|
||||
{
|
||||
int ret;
|
||||
if (SymFromAddr(p, uintptr_t(stack[i]), 0, symbol))
|
||||
ret = snprintf(out, len, "%d: %s\n", i, symbol->Name);
|
||||
else
|
||||
ret = snprintf(out, len, "%d: <unknown>\n", i);
|
||||
|
||||
out += ret;
|
||||
len -= ret;
|
||||
}
|
||||
free(symbol);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void print_backtrace(char* out, int len) {}
|
||||
|
|
Loading…
Reference in New Issue