~ubuntu-branches/ubuntu/utopic/cmake/utopic

« back to all changes in this revision

Viewing changes to Source/kwsys/SystemInformation.cxx

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-10-10 12:54:39 UTC
  • mfrom: (1.14.7)
  • Revision ID: package-import@ubuntu.com-20131010125439-h0ahaj004on6oj92
Tags: 2.8.12-0ubuntu1
New upstream release LP: #1246701

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
# include <winsock.h> // WSADATA, include before sys/types.h
19
19
#endif
20
20
 
 
21
#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE)
 
22
# define _GNU_SOURCE
 
23
#endif
 
24
 
21
25
// TODO:
22
26
// We need an alternative implementation for many functions in this file
23
27
// when USE_ASM_INSTRUCTIONS gets defined as 0.
114
118
#  define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
115
119
# endif
116
120
# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 >= 1050
117
 
#  include <execinfo.h>
118
 
#  define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
 
121
#  if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
 
122
#   include <execinfo.h>
 
123
#   if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
 
124
#     include <cxxabi.h>
 
125
#   endif
 
126
#   if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
 
127
#     include <dlfcn.h>
 
128
#   endif
 
129
#  endif
119
130
# endif
120
131
#endif
121
132
 
130
141
#   define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN
131
142
#  endif
132
143
# endif
133
 
# if defined(__GNUC__)
 
144
# if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
134
145
#  include <execinfo.h>
135
 
#  if !(defined(__LSB_VERSION__) && __LSB_VERSION__ < 41)
136
 
#   define KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE
 
146
#  if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
 
147
#    include <cxxabi.h>
 
148
#  endif
 
149
#  if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
 
150
#    include <dlfcn.h>
137
151
#  endif
138
152
# endif
139
153
# if defined(KWSYS_CXX_HAS_RLIMIT64)
357
371
  static
358
372
  void SetStackTraceOnError(int enable);
359
373
 
 
374
  // get current stack
 
375
  static
 
376
  kwsys_stl::string GetProgramStack(int firstFrame, int wholePath);
 
377
 
360
378
  /** Run the different checks */
361
379
  void RunCPUCheck();
362
380
  void RunOSCheck();
812
830
  SystemInformationImplementation::SetStackTraceOnError(enable);
813
831
}
814
832
 
 
833
kwsys_stl::string SystemInformation::GetProgramStack(int firstFrame, int wholePath)
 
834
{
 
835
  return SystemInformationImplementation::GetProgramStack(firstFrame, wholePath);
 
836
}
 
837
 
815
838
/** Run the different checks */
816
839
void SystemInformation::RunCPUCheck()
817
840
{
908
931
        }
909
932
      continue;
910
933
      }
 
934
    char *pBuf=buf;
 
935
    while(*pBuf)
 
936
      {
 
937
      if (*pBuf=='\n') *pBuf='\0';
 
938
      pBuf+=1;
 
939
      }
911
940
    lines.push_back(buf);
912
941
    ++nRead;
913
942
    }
1046
1075
#if defined(__linux) || defined(__APPLE__)
1047
1076
  kwsys_ios::ostringstream oss;
1048
1077
  oss
 
1078
     << kwsys_ios::endl
1049
1079
     << "=========================================================" << kwsys_ios::endl
1050
1080
     << "Process id " << getpid() << " ";
1051
1081
  switch (sigNo)
1052
1082
    {
 
1083
    case SIGINT:
 
1084
      oss << "Caught SIGINT";
 
1085
      break;
 
1086
 
 
1087
    case SIGTERM:
 
1088
      oss << "Caught SIGTERM";
 
1089
      break;
 
1090
 
 
1091
    case SIGABRT:
 
1092
      oss << "Caught SIGABRT";
 
1093
      break;
 
1094
 
1053
1095
    case SIGFPE:
1054
 
      oss << "Caught SIGFPE ";
 
1096
      oss
 
1097
        << "Caught SIGFPE at "
 
1098
        << (sigInfo->si_addr==0?"0x":"")
 
1099
        << sigInfo->si_addr
 
1100
        <<  " ";
1055
1101
      switch (sigInfo->si_code)
1056
1102
        {
1057
1103
# if defined(FPE_INTDIV)
1099
1145
      break;
1100
1146
 
1101
1147
    case SIGSEGV:
1102
 
      oss << "Caught SIGSEGV ";
 
1148
      oss
 
1149
        << "Caught SIGSEGV at "
 
1150
        << (sigInfo->si_addr==0?"0x":"")
 
1151
        << sigInfo->si_addr
 
1152
        <<  " ";
1103
1153
      switch (sigInfo->si_code)
1104
1154
        {
1105
1155
        case SEGV_MAPERR:
1116
1166
        }
1117
1167
      break;
1118
1168
 
1119
 
    case SIGINT:
1120
 
      oss << "Caught SIGTERM";
1121
 
      break;
1122
 
 
1123
 
    case SIGTERM:
1124
 
      oss << "Caught SIGTERM";
1125
 
      break;
1126
 
 
1127
1169
    case SIGBUS:
1128
 
      oss << "Caught SIGBUS type ";
 
1170
      oss
 
1171
        << "Caught SIGBUS at "
 
1172
        << (sigInfo->si_addr==0?"0x":"")
 
1173
        << sigInfo->si_addr
 
1174
        <<  " ";
1129
1175
      switch (sigInfo->si_code)
1130
1176
        {
1131
1177
        case BUS_ADRALN:
1134
1180
 
1135
1181
# if defined(BUS_ADRERR)
1136
1182
        case BUS_ADRERR:
1137
 
          oss << "non-exestent physical address";
 
1183
          oss << "nonexistent physical address";
1138
1184
          break;
1139
1185
# endif
1140
1186
 
1141
1187
# if defined(BUS_OBJERR)
1142
1188
        case BUS_OBJERR:
1143
 
          oss << "object specific hardware error";
 
1189
          oss << "object-specific hardware error";
 
1190
          break;
 
1191
# endif
 
1192
 
 
1193
# if defined(BUS_MCEERR_AR)
 
1194
        case BUS_MCEERR_AR:
 
1195
          oss << "Hardware memory error consumed on a machine check; action required.";
 
1196
          break;
 
1197
# endif
 
1198
 
 
1199
# if defined(BUS_MCEERR_AO)
 
1200
        case BUS_MCEERR_AO:
 
1201
          oss << "Hardware memory error detected in process but not consumed; action optional.";
1144
1202
          break;
1145
1203
# endif
1146
1204
 
1151
1209
      break;
1152
1210
 
1153
1211
    case SIGILL:
1154
 
      oss << "Caught SIGILL ";
 
1212
      oss
 
1213
        << "Caught SIGILL at "
 
1214
        << (sigInfo->si_addr==0?"0x":"")
 
1215
        << sigInfo->si_addr
 
1216
        <<  " ";
1155
1217
      switch (sigInfo->si_code)
1156
1218
        {
1157
1219
        case ILL_ILLOPC:
1205
1267
      oss << "Caught " << sigNo << " code " << sigInfo->si_code;
1206
1268
      break;
1207
1269
    }
1208
 
  oss << kwsys_ios::endl;
1209
 
#if defined(KWSYS_SYSTEMINFORMATION_HAVE_BACKTRACE)
1210
 
  oss << "Program Stack:" << kwsys_ios::endl;
1211
 
  void *stackSymbols[128];
1212
 
  int n=backtrace(stackSymbols,128);
1213
 
  char **stackText=backtrace_symbols(stackSymbols,n);
1214
 
  for (int i=0; i<n; ++i)
1215
 
    {
1216
 
    oss << "  " << stackText[i] << kwsys_ios::endl;
1217
 
    }
1218
 
#endif
1219
1270
  oss
1220
 
     << "=========================================================" << kwsys_ios::endl;
 
1271
    << kwsys_ios::endl
 
1272
    << "Program Stack:" << kwsys_ios::endl
 
1273
    << SystemInformationImplementation::GetProgramStack(2,0)
 
1274
    << "=========================================================" << kwsys_ios::endl;
1221
1275
  kwsys_ios::cerr << oss.str() << kwsys_ios::endl;
 
1276
 
 
1277
  // restore the previously registered handlers
 
1278
  // and abort
 
1279
  SystemInformationImplementation::SetStackTraceOnError(0);
1222
1280
  abort();
1223
1281
#else
1224
1282
  // avoid warning C4100
1227
1285
#endif
1228
1286
}
1229
1287
#endif
 
1288
 
 
1289
#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
 
1290
#define safes(_arg)((_arg)?(_arg):"???")
 
1291
 
 
1292
// Description:
 
1293
// A container for symbol properties. Each instance
 
1294
// must be Initialized.
 
1295
class SymbolProperties
 
1296
{
 
1297
public:
 
1298
  SymbolProperties();
 
1299
 
 
1300
  // Description:
 
1301
  // The SymbolProperties instance must be initialized by
 
1302
  // passing a stack address.
 
1303
  void Initialize(void *address);
 
1304
 
 
1305
  // Description:
 
1306
  // Get the symbol's stack address.
 
1307
  void *GetAddress() const { return this->Address; }
 
1308
 
 
1309
  // Description:
 
1310
  // If not set paths will be removed. eg, from a binary
 
1311
  // or source file.
 
1312
  void SetReportPath(int rp){ this->ReportPath=rp; }
 
1313
 
 
1314
  // Description:
 
1315
  // Set/Get the name of the binary file that the symbol
 
1316
  // is found in.
 
1317
  void SetBinary(const char *binary)
 
1318
    { this->Binary=safes(binary); }
 
1319
 
 
1320
  kwsys_stl::string GetBinary() const;
 
1321
 
 
1322
  // Description:
 
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); }
 
1327
 
 
1328
  kwsys_stl::string GetFunction() const
 
1329
    { return this->Function; }
 
1330
 
 
1331
  // Description:
 
1332
  // Set/Get the name of the source file where the symbol
 
1333
  // is defined.
 
1334
  void SetSourceFile(const char *sourcefile)
 
1335
    { this->SourceFile=safes(sourcefile); }
 
1336
 
 
1337
  kwsys_stl::string GetSourceFile() const
 
1338
    { return this->GetFileName(this->SourceFile); }
 
1339
 
 
1340
  // Description:
 
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; }
 
1344
 
 
1345
  // Description:
 
1346
  // Set the address where the biinary image is mapped
 
1347
  // into memory.
 
1348
  void SetBinaryBaseAddress(void *address)
 
1349
    { this->BinaryBaseAddress=address; }
 
1350
 
 
1351
private:
 
1352
  void *GetRealAddress() const
 
1353
    { return (void*)((char*)this->Address-(char*)this->BinaryBaseAddress); }
 
1354
 
 
1355
  kwsys_stl::string GetFileName(const kwsys_stl::string &path) const;
 
1356
  kwsys_stl::string Demangle(const char *symbol) const;
 
1357
 
 
1358
private:
 
1359
  kwsys_stl::string Binary;
 
1360
  void *BinaryBaseAddress;
 
1361
  void *Address;
 
1362
  kwsys_stl::string SourceFile;
 
1363
  kwsys_stl::string Function;
 
1364
  long LineNumber;
 
1365
  int ReportPath;
 
1366
};
 
1367
 
 
1368
// --------------------------------------------------------------------------
 
1369
kwsys_ios::ostream &operator<<(
 
1370
      kwsys_ios::ostream &os,
 
1371
      const SymbolProperties &sp)
 
1372
{
 
1373
#if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
 
1374
  os
 
1375
    << kwsys_ios::hex << sp.GetAddress() << " : "
 
1376
    << sp.GetFunction()
 
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]);
 
1384
  free(syminfo);
 
1385
#else
 
1386
  (void)os;
 
1387
  (void)sp;
 
1388
#endif
 
1389
  return os;
 
1390
}
 
1391
 
 
1392
// --------------------------------------------------------------------------
 
1393
SymbolProperties::SymbolProperties()
 
1394
{
 
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();
 
1409
}
 
1410
 
 
1411
// --------------------------------------------------------------------------
 
1412
kwsys_stl::string SymbolProperties::GetFileName(const kwsys_stl::string &path) const
 
1413
{
 
1414
  kwsys_stl::string file(path);
 
1415
  if (!this->ReportPath)
 
1416
    {
 
1417
    size_t at = file.rfind("/");
 
1418
    if (at!=kwsys_stl::string::npos)
 
1419
      {
 
1420
      file = file.substr(at+1,kwsys_stl::string::npos);
 
1421
      }
 
1422
    }
 
1423
  return file;
 
1424
}
 
1425
 
 
1426
// --------------------------------------------------------------------------
 
1427
kwsys_stl::string SymbolProperties::GetBinary() const
 
1428
{
 
1429
// only linux has proc fs
 
1430
#if defined(__linux__)
 
1431
  if (this->Binary=="/proc/self/exe")
 
1432
    {
 
1433
    kwsys_stl::string binary;
 
1434
    char buf[1024]={'\0'};
 
1435
    ssize_t ll=0;
 
1436
    if ((ll=readlink("/proc/self/exe",buf,1024))>0)
 
1437
      {
 
1438
      buf[ll]='\0';
 
1439
      binary=buf;
 
1440
      }
 
1441
    else
 
1442
      {
 
1443
      binary="/proc/self/exe";
 
1444
      }
 
1445
    return this->GetFileName(binary);
 
1446
    }
 
1447
#endif
 
1448
  return this->GetFileName(this->Binary);
 
1449
}
 
1450
 
 
1451
// --------------------------------------------------------------------------
 
1452
kwsys_stl::string SymbolProperties::Demangle(const char *symbol) const
 
1453
{
 
1454
  kwsys_stl::string result = safes(symbol);
 
1455
#if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
 
1456
  int status = 0;
 
1457
  size_t bufferLen = 1024;
 
1458
  char *buffer = (char*)malloc(1024);
 
1459
  char *demangledSymbol =
 
1460
    abi::__cxa_demangle(symbol, buffer, &bufferLen, &status);
 
1461
  if (!status)
 
1462
    {
 
1463
    result = demangledSymbol;
 
1464
    }
 
1465
  free(buffer);
 
1466
#else
 
1467
  (void)symbol;
 
1468
#endif
 
1469
  return result;
 
1470
}
 
1471
 
 
1472
// --------------------------------------------------------------------------
 
1473
void SymbolProperties::Initialize(void *address)
 
1474
{
 
1475
  this->Address = address;
 
1476
#if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
 
1477
  // first fallback option can demangle c++ functions
 
1478
  Dl_info info;
 
1479
  int ierr=dladdr(this->Address,&info);
 
1480
  if (ierr && info.dli_sname && info.dli_saddr)
 
1481
    {
 
1482
    this->SetBinary(info.dli_fname);
 
1483
    this->SetFunction(info.dli_sname);
 
1484
    }
 
1485
#else
 
1486
  // second fallback use builtin backtrace_symbols
 
1487
  // to decode the bactrace.
 
1488
#endif
 
1489
}
 
1490
#endif // don't define this class if we're not using it
 
1491
 
1230
1492
} // anonymous namespace
1231
1493
 
 
1494
 
1232
1495
SystemInformationImplementation::SystemInformationImplementation()
1233
1496
{
1234
1497
  this->TotalVirtualMemory = 0;
1471
1734
      {
1472
1735
      char host[NI_MAXHOST]={'\0'};
1473
1736
 
1474
 
      int addrlen
 
1737
      socklen_t addrlen
1475
1738
        = (fam==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6));
1476
1739
 
1477
1740
      ierr=getnameinfo(
3336
3599
}
3337
3600
 
3338
3601
/**
 
3602
return current program stack in a string
 
3603
demangle cxx symbols if possible.
 
3604
*/
 
3605
kwsys_stl::string SystemInformationImplementation::GetProgramStack(
 
3606
      int firstFrame,
 
3607
      int wholePath)
 
3608
{
 
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"
 
3616
#else
 
3617
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
 
3618
    "WARNING: Function names will not be demangled because "
 
3619
    "dladdr is not available.\n"
 
3620
# endif
 
3621
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
 
3622
    "WARNING: Function names will not be demangled "
 
3623
    "because cxxabi is not available.\n"
 
3624
# endif
 
3625
#endif
 
3626
    ;
 
3627
 
 
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)
 
3633
    {
 
3634
    SymbolProperties symProps;
 
3635
    symProps.SetReportPath(wholePath);
 
3636
    symProps.Initialize(stackSymbols[i]);
 
3637
    oss << symProps << kwsys_ios::endl;
 
3638
    }
 
3639
#else
 
3640
  (void)firstFrame;
 
3641
  (void)wholePath;
 
3642
#endif
 
3643
  programStack += oss.str();
 
3644
 
 
3645
  return programStack;
 
3646
}
 
3647
 
 
3648
 
 
3649
/**
3339
3650
when set print stack trace in response to common signals.
3340
3651
*/
3341
3652
void SystemInformationImplementation::SetStackTraceOnError(int enable)
3342
3653
{
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;
3349
3661
  static struct sigaction saBUSOrig;
3350
3662
  static struct sigaction saFPEOrig;
3351
3663
 
 
3664
 
3352
3665
  if (enable && !saOrigValid)
3353
3666
    {
3354
3667
    // save the current actions
 
3668
    sigaction(SIGABRT,0,&saABRTOrig);
3355
3669
    sigaction(SIGSEGV,0,&saSEGVOrig);
3356
3670
    sigaction(SIGTERM,0,&saTERMOrig);
3357
3671
    sigaction(SIGINT,0,&saINTOrig);
3365
3679
    // install ours
3366
3680
    struct sigaction sa;
3367
3681
    sa.sa_sigaction=(SigAction)StacktraceSignalHandler;
3368
 
    sa.sa_flags=SA_SIGINFO|SA_RESTART;
 
3682
    sa.sa_flags=SA_SIGINFO|SA_RESTART|SA_RESETHAND;
3369
3683
    sigemptyset(&sa.sa_mask);
3370
3684
 
 
3685
    sigaction(SIGABRT,&sa,0);
3371
3686
    sigaction(SIGSEGV,&sa,0);
3372
3687
    sigaction(SIGTERM,&sa,0);
3373
3688
    sigaction(SIGINT,&sa,0);
3379
3694
  if (!enable && saOrigValid)
3380
3695
    {
3381
3696
    // restore previous actions
 
3697
    sigaction(SIGABRT,&saABRTOrig,0);
3382
3698
    sigaction(SIGSEGV,&saSEGVOrig,0);
3383
3699
    sigaction(SIGTERM,&saTERMOrig,0);
3384
3700
    sigaction(SIGINT,&saINTOrig,0);
3487
3803
    bool have[6] = { false, false, false, false, false, false };
3488
3804
    unsigned long value[6];
3489
3805
    int count = 0;
3490
 
    while(fgets(buffer, sizeof(buffer), fd))
 
3806
    while(fgets(buffer, static_cast<int>(sizeof(buffer)), fd))
3491
3807
      {
3492
3808
      for(int i=0; i < 6; ++i)
3493
3809
        {