1289
#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
1290
#define safes(_arg)((_arg)?(_arg):"???")
1293
// A container for symbol properties. Each instance
1294
// must be Initialized.
1295
class SymbolProperties
1301
// The SymbolProperties instance must be initialized by
1302
// passing a stack address.
1303
void Initialize(void *address);
1306
// Get the symbol's stack address.
1307
void *GetAddress() const { return this->Address; }
1310
// If not set paths will be removed. eg, from a binary
1312
void SetReportPath(int rp){ this->ReportPath=rp; }
1315
// Set/Get the name of the binary file that the symbol
1317
void SetBinary(const char *binary)
1318
{ this->Binary=safes(binary); }
1320
kwsys_stl::string GetBinary() const;
1323
// Set the name of the function that the symbol is found in.
1324
// If c++ demangling is supported it will be demangled.
1325
void SetFunction(const char *function)
1326
{ this->Function=this->Demangle(function); }
1328
kwsys_stl::string GetFunction() const
1329
{ return this->Function; }
1332
// Set/Get the name of the source file where the symbol
1334
void SetSourceFile(const char *sourcefile)
1335
{ this->SourceFile=safes(sourcefile); }
1337
kwsys_stl::string GetSourceFile() const
1338
{ return this->GetFileName(this->SourceFile); }
1341
// Set/Get the line number where the symbol is defined
1342
void SetLineNumber(long linenumber){ this->LineNumber=linenumber; }
1343
long GetLineNumber() const { return this->LineNumber; }
1346
// Set the address where the biinary image is mapped
1348
void SetBinaryBaseAddress(void *address)
1349
{ this->BinaryBaseAddress=address; }
1352
void *GetRealAddress() const
1353
{ return (void*)((char*)this->Address-(char*)this->BinaryBaseAddress); }
1355
kwsys_stl::string GetFileName(const kwsys_stl::string &path) const;
1356
kwsys_stl::string Demangle(const char *symbol) const;
1359
kwsys_stl::string Binary;
1360
void *BinaryBaseAddress;
1362
kwsys_stl::string SourceFile;
1363
kwsys_stl::string Function;
1368
// --------------------------------------------------------------------------
1369
kwsys_ios::ostream &operator<<(
1370
kwsys_ios::ostream &os,
1371
const SymbolProperties &sp)
1373
#if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
1375
<< kwsys_ios::hex << sp.GetAddress() << " : "
1377
<< " [(" << sp.GetBinary() << ") "
1378
<< sp.GetSourceFile() << ":"
1379
<< kwsys_ios::dec << sp.GetLineNumber() << "]";
1380
#elif defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
1381
void *addr = sp.GetAddress();
1382
char **syminfo = backtrace_symbols(&addr,1);
1383
os << safes(syminfo[0]);
1392
// --------------------------------------------------------------------------
1393
SymbolProperties::SymbolProperties()
1395
// not using an initializer list
1396
// to avoid some PGI compiler warnings
1397
this->SetBinary("???");
1398
this->SetBinaryBaseAddress(NULL);
1399
this->Address = NULL;
1400
this->SetSourceFile("???");
1401
this->SetFunction("???");
1402
this->SetLineNumber(-1);
1403
this->SetReportPath(0);
1404
// avoid PGI compiler warnings
1405
this->GetRealAddress();
1406
this->GetFunction();
1407
this->GetSourceFile();
1408
this->GetLineNumber();
1411
// --------------------------------------------------------------------------
1412
kwsys_stl::string SymbolProperties::GetFileName(const kwsys_stl::string &path) const
1414
kwsys_stl::string file(path);
1415
if (!this->ReportPath)
1417
size_t at = file.rfind("/");
1418
if (at!=kwsys_stl::string::npos)
1420
file = file.substr(at+1,kwsys_stl::string::npos);
1426
// --------------------------------------------------------------------------
1427
kwsys_stl::string SymbolProperties::GetBinary() const
1429
// only linux has proc fs
1430
#if defined(__linux__)
1431
if (this->Binary=="/proc/self/exe")
1433
kwsys_stl::string binary;
1434
char buf[1024]={'\0'};
1436
if ((ll=readlink("/proc/self/exe",buf,1024))>0)
1443
binary="/proc/self/exe";
1445
return this->GetFileName(binary);
1448
return this->GetFileName(this->Binary);
1451
// --------------------------------------------------------------------------
1452
kwsys_stl::string SymbolProperties::Demangle(const char *symbol) const
1454
kwsys_stl::string result = safes(symbol);
1455
#if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
1457
size_t bufferLen = 1024;
1458
char *buffer = (char*)malloc(1024);
1459
char *demangledSymbol =
1460
abi::__cxa_demangle(symbol, buffer, &bufferLen, &status);
1463
result = demangledSymbol;
1472
// --------------------------------------------------------------------------
1473
void SymbolProperties::Initialize(void *address)
1475
this->Address = address;
1476
#if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
1477
// first fallback option can demangle c++ functions
1479
int ierr=dladdr(this->Address,&info);
1480
if (ierr && info.dli_sname && info.dli_saddr)
1482
this->SetBinary(info.dli_fname);
1483
this->SetFunction(info.dli_sname);
1486
// second fallback use builtin backtrace_symbols
1487
// to decode the bactrace.
1490
#endif // don't define this class if we're not using it
1230
1492
} // anonymous namespace
1232
1495
SystemInformationImplementation::SystemInformationImplementation()
1234
1497
this->TotalVirtualMemory = 0;
3602
return current program stack in a string
3603
demangle cxx symbols if possible.
3605
kwsys_stl::string SystemInformationImplementation::GetProgramStack(
3609
kwsys_stl::string programStack = ""
3610
#if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
3611
"WARNING: The stack could not be examined "
3612
"because backtrace is not supported.\n"
3613
#elif !defined(KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD)
3614
"WARNING: The stack trace will not use advanced "
3615
"capabilities because this is a release build.\n"
3617
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
3618
"WARNING: Function names will not be demangled because "
3619
"dladdr is not available.\n"
3621
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
3622
"WARNING: Function names will not be demangled "
3623
"because cxxabi is not available.\n"
3628
kwsys_ios::ostringstream oss;
3629
#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
3630
void *stackSymbols[256];
3631
int nFrames=backtrace(stackSymbols,256);
3632
for (int i=firstFrame; i<nFrames; ++i)
3634
SymbolProperties symProps;
3635
symProps.SetReportPath(wholePath);
3636
symProps.Initialize(stackSymbols[i]);
3637
oss << symProps << kwsys_ios::endl;
3643
programStack += oss.str();
3645
return programStack;
3339
3650
when set print stack trace in response to common signals.
3341
3652
void SystemInformationImplementation::SetStackTraceOnError(int enable)
3343
3654
#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
3344
3655
static int saOrigValid=0;
3656
static struct sigaction saABRTOrig;
3345
3657
static struct sigaction saSEGVOrig;
3346
3658
static struct sigaction saTERMOrig;
3347
3659
static struct sigaction saINTOrig;