#include <string>
#include <vector>
#include "TString.h"
#include <malloc.h>
#include <execinfo.h>
#include <cxxabi.h>
#include "TMemStatDepend.h"
void *g_global_stack_end = NULL;
#if defined(R__GNU) && (defined(R__LINUX) || defined(R__HURD)) && !defined(__alpha__)
#define G__builtin_return_address(N) \
((__builtin_frame_address(N) == NULL) || \
(__builtin_frame_address(N) >= g_global_stack_end) || \
(__builtin_frame_address(N) < __builtin_frame_address(0))) ? \
NULL : __builtin_return_address(N)
#define _RET_ADDR(x) case x: return G__builtin_return_address(x);
#endif
using namespace std;
ClassImp(TMemStatDepend)
static void *return_address(int _frame)
{
switch (_frame) {
_RET_ADDR(0);_RET_ADDR(1);_RET_ADDR(2);_RET_ADDR(3);_RET_ADDR(4);_RET_ADDR(5);_RET_ADDR(6);_RET_ADDR(7);
_RET_ADDR(8);_RET_ADDR(9);_RET_ADDR(10);_RET_ADDR(11);_RET_ADDR(12);_RET_ADDR(13);_RET_ADDR(14);
_RET_ADDR(15);_RET_ADDR(16);_RET_ADDR(17);_RET_ADDR(18);_RET_ADDR(19);_RET_ADDR(20);_RET_ADDR(21);
_RET_ADDR(22);_RET_ADDR(23);_RET_ADDR(24);_RET_ADDR(25);_RET_ADDR(26);_RET_ADDR(27);_RET_ADDR(28);
_RET_ADDR(29);_RET_ADDR(30);_RET_ADDR(31);_RET_ADDR(32);_RET_ADDR(33);_RET_ADDR(34);_RET_ADDR(35);
default:
return NULL;
}
}
size_t builtin_return_address(void **_Container, size_t _limit)
{
size_t i(0);
void *addr;
for (i = 0; (i < _limit) && (addr = return_address(i)); ++i)
_Container[i] = addr;
return i;
}
TMemStatDepend::MallocHookFunc_t TMemStatDepend::GetMallocHook()
{
return __malloc_hook;
}
TMemStatDepend::FreeHookFunc_t TMemStatDepend::GetFreeHook()
{
return __free_hook;
}
void TMemStatDepend::SetMallocHook(MallocHookFunc_t p)
{
__malloc_hook = p;
}
void TMemStatDepend::SetFreeHook(FreeHookFunc_t p)
{
__free_hook = p;
}
size_t TMemStatDepend::Backtrace(void **trace, size_t dsize, Bool_t _bUseGNUBuildinBacktrace)
{
if ( _bUseGNUBuildinBacktrace )
{
#if defined(R__GNU) && (defined(R__LINUX) || defined(R__HURD)) && !defined(__alpha__)
return builtin_return_address(trace, dsize);
#endif
return 0;
}
return backtrace(trace, dsize);
}
char** TMemStatDepend::BacktraceSymbols(void **trace, size_t size)
{
#if defined(R__GNU) && (defined(R__LINUX) || defined(R__HURD)) && !defined(__alpha__)
return backtrace_symbols(trace, size);
#endif
return 0;
}
void TMemStatDepend::GetSymbols(void *_pFunction,
TString &_strInfo, TString &_strLib, TString &_strFun, TString &)
{
#if defined(R__GNU) && (defined(R__LINUX) || defined(R__HURD)) && !defined(__alpha__)
char ** code = backtrace_symbols(&_pFunction, 1);
if (!code || !code[0])
return;
const string codeInfo(code[0]);
free(code);
_strInfo = codeInfo.c_str();
const string::size_type pos_begin = codeInfo.find_first_of("( [");
if (string::npos == pos_begin) {
_strLib = codeInfo;
return;
}
_strLib = codeInfo.substr(0, pos_begin);
string::size_type pos_end = codeInfo.find('+', pos_begin);
if (string::npos == pos_end) {
pos_end = codeInfo.find(')', pos_begin);
if (string::npos == pos_end)
return;
}
const string func(codeInfo.substr(pos_begin + 1, pos_end - pos_begin - 1));
int status(0);
char *ch = abi::__cxa_demangle(func.c_str(), 0, 0, &status);
if (!ch)
return;
_strFun = (!status) ? ch : func.c_str();
free(ch);
#endif
}
void TMemStatDepend::Demangle(char *codeInfo, TString &str)
{
#if defined(R__GNU) && (defined(R__LINUX) || defined(R__HURD)) && !defined(__alpha__)
int status = 0;
char *ch = abi::__cxa_demangle(codeInfo, 0, 0, &status);
if (ch) {
str = ch;
free(ch);
} else {
str = "unknown";
}
#endif
}
Last change: Mon Sep 15 08:33:44 2008
Last generated: 2008-09-15 08:33
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.