Gaudi Framework, version v20r3

Generated: 24 Nov 2008

System.cpp

Go to the documentation of this file.
00001 // $Id: System.cpp,v 1.45 2008/10/27 21:30:32 marcocle Exp $
00002 //====================================================================
00003 //      System.cpp
00004 //--------------------------------------------------------------------
00005 //
00006 //      Package    : System (The LHCb System service)
00007 //
00008 //  Description: Implementation of Systems internals
00009 //
00010 //      Author     : M.Frank
00011 //  Created    : 13/1/99
00012 //      Changes    :
00013 //====================================================================
00014 #define SYSTEM_SYSTEM_CPP
00015 #include <ctime>
00016 #include <cstring>
00017 #include <cstdlib>
00018 #include <iomanip>
00019 #include <iostream>
00020 #include <sstream>
00021 #include <typeinfo>
00022 
00023 #include "GaudiKernel/System.h"
00024 
00025 #ifdef _WIN32
00026   #define strcasecmp  _stricmp
00027   #define strncasecmp _strnicmp
00028   #define getpid _getpid
00029   #define NOMSG
00030   #define NOGDI
00031   #include "process.h"
00032   #include "windows.h"
00033   #undef NOMSG
00034   #undef NOGDI
00035   static const char* SHLIB_SUFFIX = ".dll";
00036 #else  // UNIX...: first the EGCS stuff, then the OS dependent includes
00037   static const char* SHLIB_SUFFIX = ".so";
00038   #include <errno.h>
00039   #include <string.h>
00040   #include "sys/times.h"
00041   #include "unistd.h"
00042   #include "libgen.h"
00043   #include <cstdio>
00044   #include <cxxabi.h>
00045 #if defined(linux) || defined(__APPLE__)
00046   #include "dlfcn.h"
00047   #include <sys/utsname.h>
00048   #include <unistd.h>
00049 #elif __hpux
00050   #include "dl.h"
00051 struct HMODULE {
00052   shl_descriptor dsc;
00053   long           numSym;
00054   shl_symbol*    sym;
00055 };
00056 #endif
00057 
00058 #endif
00059 
00060 // Note: __attribute__ is a GCC keyword available since GCC 3.4
00061 #ifdef __GNUC__
00062 #  if __GNUC__ < 3 || \
00063       (__GNUC__ == 3 && (__GNUC_MINOR__ < 4 ))
00064 // GCC < 3.4
00065 #    define __attribute__(x)
00066 #  endif
00067 #else
00068 // non-GCC
00069 #  define __attribute__(x)
00070 #endif
00071 
00072 static std::vector<std::string> s_argvStrings;
00073 static std::vector<const char*> s_argvChars;
00074 
00075 static unsigned long doLoad(const std::string& name, System::ImageHandle* handle)  {
00076 #ifdef _WIN32
00077   void* mh = ::LoadLibrary( name.length() == 0 ? System::exeName().c_str() : name.c_str());
00078   *handle = mh;
00079 #else
00080   const char* path = name.c_str();
00081 #if defined(linux) || defined(__APPLE__)
00082   void *mh = ::dlopen(name.length() == 0 ? 0 : path, RTLD_LAZY | RTLD_GLOBAL);
00083   *handle = mh;
00084 #elif __hpux
00085   shl_t mh = ::shl_load(name.length() == 0 ? 0 : path, BIND_IMMEDIATE | BIND_VERBOSE, 0);
00086   HMODULE* mod = new HMODULE;
00087   if ( 0 != mh ) {
00088     if ( 0 != ::shl_gethandle_r(mh, &mod->dsc) ) {
00089       std::cout << "System::loadDynamicLib>" << ::strerror(getLastError()) << std::endl;
00090     }
00091     else {
00092       typedef void* (*___all)();
00093       ___all _alloc = (___all)malloc;
00094       mod->numSym = ::shl_getsymbols(mod->dsc.handle, TYPE_PROCEDURE, EXPORT_SYMBOLS, malloc, &mod->sym);
00095       *handle = mod;
00096     }
00097   }
00098 #endif
00099 #endif
00100   if ( 0 == *handle )   {
00101     return System::getLastError();
00102   }
00103   return 1;
00104 }
00105 
00106 static unsigned long loadWithoutEnvironment(const std::string& name, System::ImageHandle* handle)    {
00107 
00108   std::string dllName = name;
00109   long len = strlen(SHLIB_SUFFIX);
00110 
00111   // Add the suffix at the end of the library name only if necessary
00112   // FIXME: cure the logic
00113   if ((dllName.length() != 0) &&
00114       ::strncasecmp(dllName.data()+dllName.length()-len, SHLIB_SUFFIX, len) != 0) {
00115     dllName += SHLIB_SUFFIX;
00116   }
00117 
00118   // Load the library
00119   return doLoad(dllName, handle);
00120 }
00121 
00123 unsigned long System::loadDynamicLib(const std::string& name, ImageHandle* handle) {
00124   unsigned long res;
00125   // if name is empty, just load it
00126   if (name.length() == 0) {
00127     res = loadWithoutEnvironment(name, handle);
00128   } else {
00129     // If the name is a logical name (environment variable), the try
00130     // to load the corresponding library from there.
00131     std::string env = name;
00132     if ( 0 != ::getenv(env.c_str()) )    {
00133       std::string imgName = ::getenv(env.c_str());
00134       res = loadWithoutEnvironment(imgName, handle);
00135     } else {
00136       // build the dll name
00137       std::string dllName = name;
00138 #if defined(linux) || defined(__APPLE__)
00139       dllName = "lib" + dllName;
00140 #endif
00141       dllName += SHLIB_SUFFIX;
00142       // try to locate the dll using the standard PATH
00143       res = loadWithoutEnvironment(dllName, handle);
00144     }
00145     if ( res != 1 ) {
00146 #if defined(linux) || defined(__APPLE__)
00147       errno = 0xAFFEDEAD;
00148 #endif
00149      // std::cout << "System::loadDynamicLib>" << getLastErrorString() << std::endl;
00150     }
00151   }
00152   return res;
00153 }
00154 
00156 unsigned long System::unloadDynamicLib(ImageHandle handle)    {
00157 #ifdef _WIN32
00158   if ( !::FreeLibrary((HINSTANCE)handle) ) {
00159 #elif defined(linux) || defined(__APPLE__)
00160   ::dlclose( handle );
00161   if ( 0 ) {
00162 #elif __hpux
00163   // On HP we have to run finalization ourselves.....
00164   Creator pFinalize = 0;
00165   if ( getProcedureByName(handle, "_fini", &pFinalize) ) {
00166     pFinalize();
00167   }
00168   HMODULE* mod = (HMODULE*)handle;
00169   if ( 0 == ::shl_unload( mod->dsc.handle ) ) {
00170     delete mod;
00171   }
00172   else {
00173 #endif
00174     return getLastError();
00175   }
00176   return 1;
00177 }
00178 
00180 unsigned long System::getProcedureByName(ImageHandle handle, const std::string& name, EntryPoint* pFunction)    {
00181 #ifdef _WIN32
00182   *pFunction = (EntryPoint)::GetProcAddress((HINSTANCE)handle, name.data());
00183   if ( 0 == *pFunction )    {
00184     return System::getLastError();
00185   }
00186   return 1;
00187 #elif defined(linux)
00188 #if __GNUC__ < 4
00189   *pFunction = (EntryPoint)::dlsym(handle, name.c_str());
00190 #else
00191   *pFunction = FuncPtrCast<EntryPoint>(::dlsym(handle, name.c_str()));
00192 #endif
00193   if ( 0 == *pFunction )    {
00194     errno = 0xAFFEDEAD;
00195    // std::cout << "System::getProcedureByName>" << getLastErrorString() << std::endl;
00196     return 0;
00197   }
00198   return 1;
00199 #elif defined(__APPLE__)
00200   *pFunction = (EntryPoint)::dlsym(handle, name.c_str());
00201   if(!(*pFunction)) {
00202     // Try with an underscore :
00203     std::string sname = "_" + name;
00204     *pFunction = (EntryPoint)::dlsym(handle, sname.c_str());
00205   }
00206   if ( 0 == *pFunction )    {
00207     errno = 0xAFFEDEAD;
00208     std::cout << "System::getProcedureByName>" << getLastErrorString() << std::endl;
00209     //std::cout << "System::getProcedureByName> failure" << std::endl;
00210     return 0;
00211   }
00212   return 1;
00213 #elif __hpux
00214   HMODULE* mod = (HMODULE*)handle;
00215   if ( 0 != mod ) {
00216     long ll1 = name.length();
00217     for ( int i = 0; i < mod->numSym; i++ ) {
00218       long ll2 = strlen(mod->sym[i].name);
00219       if ( 0 != ::strncmp(mod->sym[i].name, name.c_str(), (ll1>ll2) ? ll1 : ll2)==0 ) {
00220               *pFunction = (EntryPoint) mod->sym[i].value;
00221               return 1;
00222       }
00223     }
00224   }
00225   return 0;
00226 #endif
00227 }
00228 
00230 unsigned long System::getProcedureByName(ImageHandle handle, const std::string& name, Creator* pFunction)    {
00231   return getProcedureByName(handle, name, (EntryPoint*)pFunction);
00232 }
00233 
00235 unsigned long System::getLastError()    {
00236 #ifdef _WIN32
00237   return ::GetLastError();
00238 #else
00239   // convert errno (int) to unsigned long
00240   return static_cast<unsigned long>(static_cast<unsigned int>(errno));
00241 #endif
00242 }
00243 
00245 const std::string System::getLastErrorString()    {
00246   const std::string errString = getErrorString(getLastError());
00247   return errString;
00248 }
00249 
00251 const std::string System::getErrorString(unsigned long error)    {
00252   std::string errString =  "";
00253 #ifdef _WIN32
00254   LPVOID lpMessageBuffer;
00255   ::FormatMessage(
00256     FORMAT_MESSAGE_ALLOCATE_BUFFER |  FORMAT_MESSAGE_FROM_SYSTEM,
00257     NULL,
00258     error,
00259     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
00260     (LPTSTR) &lpMessageBuffer,
00261     0,
00262     NULL );
00263   errString = (const char*)lpMessageBuffer;
00264   // Free the buffer allocated by the system
00265   ::LocalFree( lpMessageBuffer );
00266 #else
00267   char *cerrString(0);
00268   // Remember: for linux dl* routines must be handled differently!
00269   if ( error == 0xAFFEDEAD ) {
00270     cerrString = (char*)::dlerror();
00271     if ( 0 == cerrString ) {
00272       cerrString = ::strerror(error);
00273     }
00274     if ( 0 == cerrString ) {
00275       cerrString = (char *)"Unknown error. No information found in strerror()!";
00276     }
00277     else {
00278       errString = std::string(cerrString);
00279     }
00280     errno = 0;
00281   }
00282   else    {
00283     cerrString = ::strerror(error);
00284     errString = std::string(cerrString);
00285   }
00286 #endif
00287   return errString;
00288 }
00289 
00290 // This is a little bit complicated....but at least it gives
00291 // usable results:
00292 // Native class template:
00293 //  Spac::templa<Spac::templa<Spac::templ<Spac::templa<AAA::a,Spac::templa<double,unsigned char>>>,B::bbb>,float>
00294 // is translated under egcs to the unreadable string:
00295 //  Q24Spact6templa2ZQ24Spact6templa2ZQ24Spact5templ1ZQ24Spact6templa2ZQ23AAA1aZQ24Spact6templa2ZdZUcZQ21B3bbbZf
00296 
00297 std::string __typeName(char*&  name);
00298 std::string __className(char*& name) {
00299   std::string result;
00300   int j = 0, k, i;
00301   if ( 't' == *name ) {
00302     goto Template;
00303   }
00304   for ( i = ::strtol(name, &name, 10);  i > 0; i = ::strtol(name, &name, 10) ) {
00305     if ( j++ != 0 ) result.append("::",2);
00306     result.append(name, i);
00307     if ( *(name+=i) == 't' ) {
00308       result.append("::",2);
00309     Template:
00310       result.append(name, (i=::strtol(++name, &name, 10)));
00311       result.append("<");
00312       for (k = 0, i=::strtol(name+i, &name, 10); k < i; k++ ) {
00313         result += __typeName( ++name );
00314         if ( k+1 < i ) result += ",";
00315       }
00316       result.append(">");
00317     }
00318   }
00319   return result;
00320 }
00321 
00322 std::string __typeName(char*&  name) {
00323   if ( *name == 'Q' ) {              // Handle name spaces
00324     if ( *(++name) == '_' )          // >= 10 nested name spaces
00325       ::strtol(++name, &name, 10);   // type Q_##_...
00326     return __className(++name);
00327   }
00328   else if ( 't' == *name )  {
00329     return __className(name);
00330   }
00331   else  {
00332     std::string result;
00333     char* ptr;
00334     int i = ::strtol(name, &ptr, 10);
00335     if ( i <= 0 )  {
00336       name = ptr;
00337       while ( *name != 0 && *name != 'Z' )  {
00338         if ( *name == 'U' )  {
00339           result += "unsigned ";
00340           name++;
00341         }
00342         switch( *name++ )  {
00343         case 'c': result += "char"; break;
00344         case 's': result += "short"; break;
00345         case 'i': result += "int"; break;
00346         case 'l': result += "long"; break;
00347         case 'f': result += "float"; break;
00348         case 'd': result += "double"; break;
00349         default:  result += *(name-1);
00350         }
00351       }
00352       return result;
00353     }
00354     else {
00355       return __className(name);
00356     }
00357   }
00358 }
00359 const std::string System::typeinfoName( const std::type_info& tinfo) {
00360   return typeinfoName(tinfo.name());
00361 }
00362 const std::string System::typeinfoName( const char* class_name) {
00363   std::string result;
00364 #ifdef _WIN32
00365   long off = 0;
00366   if ( ::strncmp(class_name, "class ", 6) == 0 )   {
00367     // The returned name is prefixed with "class "
00368     off = 6;
00369   }
00370   if ( ::strncmp(class_name, "struct ", 7) == 0 )   {
00371     // The returned name is prefixed with "struct "
00372     off = 7;
00373   }
00374   if ( off > 0 )    {
00375     std::string tmp = class_name + off;
00376     long loc = 0;
00377     while( (loc = tmp.find("class ")) > 0 )  {
00378       tmp.erase(loc, 6);
00379     }
00380     loc = 0;
00381     while( (loc = tmp.find("struct ")) > 0 )  {
00382       tmp.erase(loc, 7);
00383     }
00384     result = tmp;
00385   }
00386   else  {
00387     result = class_name;
00388   }
00389   // Change any " *" to "*"
00390   while ( (off=result.find(" *")) != std::string::npos ) {
00391     result.replace(off, 2, "*");
00392   }
00393   // Change any " &" to "&"
00394   while ( (off=result.find(" &")) != std::string::npos ) {
00395     result.replace(off, 2, "&");
00396   }
00397 
00398 #elif defined(__linux) || defined(__APPLE__)
00399     if ( ::strlen(class_name) == 1 ) {
00400       // See http://www.realitydiluted.com/mirrors/reality.sgi.com/dehnert_engr/cxx/abi.pdf
00401       // for details
00402       switch(class_name[0]) {
00403       case 'v':
00404         result = "void";
00405         break;
00406       case 'w':
00407         result = "wchar_t";
00408         break;
00409       case 'b':
00410         result = "bool";
00411         break;
00412       case 'c':
00413         result = "char";
00414         break;
00415       case 'a':
00416         result = "signed char";
00417         break;
00418       case 'h':
00419         result = "unsigned char";
00420         break;
00421       case 's':
00422         result = "short";
00423         break;
00424       case 't':
00425         result = "unsigned short";
00426         break;
00427       case 'i':
00428         result = "int";
00429         break;
00430       case 'j':
00431         result = "unsigned int";
00432         break;
00433       case 'l':
00434         result = "long";
00435         break;
00436       case 'm':
00437         result = "unsigned long";
00438         break;
00439       case 'x':
00440         result = "long long";
00441         break;
00442       case 'y':
00443         result = "unsigned long long";
00444         break;
00445       case 'n':
00446         result = "__int128";
00447         break;
00448       case 'o':
00449         result = "unsigned __int128";
00450         break;
00451       case 'f':
00452         result = "float";
00453         break;
00454       case 'd':
00455         result = "double";
00456         break;
00457       case 'e':
00458         result = "long double";
00459         break;
00460       case 'g':
00461         result = "__float128";
00462         break;
00463       case 'z':
00464         result = "ellipsis";
00465         break;
00466       }
00467     }
00468     else  {
00469       int   status;
00470       char* realname;
00471       realname = abi::__cxa_demangle(class_name, 0, 0, &status);
00472       if (realname == 0) return class_name;
00473       result = realname;
00474       free(realname);
00476       std::string::size_type pos = result.find(", ");
00477       while( std::string::npos != pos ) {
00478         result.replace( pos , 2 , "," ) ;
00479         pos = result.find(", ");
00480       }
00481     }
00482 #endif
00483   return result;
00484 }
00485 
00487 const std::string& System::hostName() {
00488   static std::string host = "";
00489   if ( host == "" ) {
00490     char buffer[512];
00491     memset(buffer,0,sizeof(buffer));
00492 #ifdef _WIN32
00493     unsigned long len = sizeof(buffer);
00494     ::GetComputerName(buffer, &len);
00495 #else
00496     ::gethostname(buffer, sizeof(buffer));
00497 #endif
00498     host = buffer;
00499   }
00500   return host;
00501 }
00502 
00504 const std::string& System::osName() {
00505   static std::string osname = "";
00506 #ifdef _WIN32
00507   osname = "Windows";
00508 #else
00509   struct utsname ut;
00510   if (uname(&ut) == 0) {
00511     osname = ut.sysname;
00512   } else {
00513     osname = "UNKNOWN";
00514   }
00515 #endif
00516   return osname;
00517 }
00518 
00519 
00521 const std::string& System::osVersion() {
00522   static std::string osver = "";
00523 #ifdef _WIN32
00524   OSVERSIONINFO ut;
00525   ut.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00526   ::GetVersionEx(&ut);
00527   char ver[64];
00528   sprintf(ver,"%d.%d",ut.dwMajorVersion,ut.dwMinorVersion);
00529   osver = ver;
00530 #else
00531   struct utsname ut;
00532   if (uname(&ut) == 0) {
00533     osver = ut.release;
00534   } else {
00535     osver = "UNKNOWN";
00536   }
00537 #endif
00538   return osver;
00539 }
00540 
00542 const std::string& System::machineType() {
00543   static std::string mach = "";
00544 #ifdef _WIN32
00545   SYSTEM_INFO ut;
00546   ::GetSystemInfo(&ut);
00547   char arch[64];
00548   sprintf(arch,"%d",ut.wProcessorArchitecture);
00549   mach =  arch;
00550 #else
00551   struct utsname ut;
00552   if (uname(&ut) == 0) {
00553     mach = ut.machine;
00554   } else {
00555     mach = "UNKNOWN";
00556   }
00557 #endif
00558   return mach;
00559 }
00560 
00562 const std::string& System::accountName() {
00563   static std::string account = "";
00564   if ( account == "" ) {
00565 #ifdef _WIN32
00566     char buffer[512];
00567     unsigned long buflen = sizeof(buffer);
00568     ::GetUserName(buffer, &buflen);
00569     account = buffer;
00570 #else
00571     const char* acct = ::getlogin();
00572     if ( 0 == acct ) acct = ::getenv("LOGNAME");
00573     if ( 0 == acct ) acct = ::getenv("USER");
00574     account = (acct) ? acct : "Unknown";
00575 #endif
00576   }
00577   return account;
00578 }
00579 
00581 long System::numCmdLineArgs()   {
00582   return cmdLineArgs().size();
00583 }
00584 
00586 long System::argc()    {
00587   return cmdLineArgs().size();
00588 }
00589 
00591 const std::vector<std::string> System::cmdLineArgs()    {
00592   if ( s_argvChars.size() == 0 )    {
00593     char exe[1024];
00594 #ifdef _WIN32
00595     // For compatibility with UNIX we CANNOT use strtok!
00596     // If we would use strtok, options like -g="My world" at
00597     // the command line level would result on NT in TWO options
00598     // instead in one as in UNIX.
00599     char *next, *tmp1, *tmp2;
00600     for(LPTSTR cmd = ::GetCommandLine(); *cmd; cmd=next)   {
00601       memset(exe,0,sizeof(exe));
00602       while ( *cmd == ' ' ) cmd++;
00603       next=::strchr(cmd,' ');
00604       if ( !next ) next = cmd + strlen(cmd);
00605       if ( (tmp1=::strchr(cmd,'\"')) > 0 && tmp1 < next )  {
00606         tmp2 = ::strchr(++tmp1,'\"');
00607         if ( tmp2 > 0 )   {
00608           next = ++tmp2;
00609           if ( cmd < tmp1 ) strncpy(exe, cmd, tmp1-cmd-1);
00610           strncpy(&exe[strlen(exe)], tmp1, tmp2-tmp1-1);
00611         }
00612         else    {
00613           std::cout << "Mismatched \" in command line arguments" << std::endl;
00614           s_argvChars.erase(s_argvChars.begin(), s_argvChars.end());
00615           s_argvStrings.erase(s_argvStrings.begin(), s_argvStrings.end());
00616           return s_argvStrings;
00617         }
00618       }
00619       else    {
00620         strncpy(exe, cmd, next-cmd);
00621       }
00622       s_argvStrings.push_back(exe);
00623       s_argvChars.push_back( s_argvStrings.back().c_str());
00624     }
00625 #elif defined(linux) || defined(__APPLE__)
00626     sprintf(exe, "/proc/%d/cmdline", ::getpid());
00627     FILE *cmdLine = ::fopen(exe,"r");
00628     char cmd[1024];
00629     if ( cmdLine )   {
00630       long len = fread(cmd, sizeof(char), sizeof(cmd), cmdLine);
00631       if ( len > 0 )   {
00632         cmd[len] = 0;
00633         for ( char* token = cmd; token-cmd < len; token += strlen(token)+1 )  {
00634           s_argvStrings.push_back(token);
00635           s_argvChars.push_back( s_argvStrings.back().c_str());
00636         }
00637         s_argvStrings[0] = exeName();
00638         s_argvChars[0]   = s_argvStrings[0].c_str();
00639       }
00640     }
00641     ::fclose(cmdLine);
00642 #endif
00643   }
00644   return s_argvStrings;
00645 }
00646 
00648 char** System::argv()    {
00650   if( s_argvChars.empty() ) { cmdLineArgs(); }  
00651 
00652   // We rely here on the fact that a vector's allocation table is contiguous
00653   return (char**)&s_argvChars[0];
00654 }
00655 
00657 const std::string System::getEnv(const char* var) {
00658   char* env;
00659   if  ( (env = getenv(var)) != 0 ) {
00660     return env;
00661   } else {
00662     return "UNKNOWN";
00663   }
00664 }
00665 
00667 #if defined(__APPLE__)
00668 // Needed for _NSGetEnviron(void)
00669 #include "crt_externs.h"
00670 #endif
00671 const std::vector<std::string> System::getEnv() {
00672 #if defined(_WIN32)
00673 #  define environ _environ
00674 #elif defined(linux)
00675   extern char **environ;
00676 #elif defined(__APPLE__)
00677   static char **environ = *_NSGetEnviron();
00678 #endif
00679   std::vector<std::string> vars;
00680   for (int i=0; environ[i] != 0; ++i) {
00681     vars.push_back(environ[i]);
00682   }
00683   return vars;
00684 }
00685 
00686 // -----------------------------------------------------------------------------
00687 // backtrace utilities
00688 // -----------------------------------------------------------------------------
00689 #ifdef __linux
00690 #include <execinfo.h>
00691 #endif
00692 
00693 int System::backTrace(void** addresses __attribute__ ((unused)),
00694                        const int depth __attribute__ ((unused)))
00695 {
00696 
00697 #ifdef __linux
00698 
00699   int count = backtrace( addresses, depth );
00700   if ( count > 0 ) {
00701     return count;
00702   } else {
00703     return 0;
00704   }
00705 
00706 #else // windows and osx parts not implemented
00707   return 0;
00708 #endif
00709 
00710 }
00711 
00712 bool System::backTrace(std::string& btrace, const int depth, const int offset)
00713 {
00714   // Always hide the first two levels of the stack trace (that's us)
00715   const int totalOffset = offset + 2;
00716   const int totalDepth = depth + totalOffset;
00717 
00718   std::string fnc, lib;
00719 
00720   void** addresses = (void**) malloc(totalDepth*sizeof(void *));
00721   if ( addresses != 0 ){
00722     int count = System::backTrace(addresses,totalDepth);
00723     for (int i = totalOffset; i < count; ++i) {
00724       void *addr = 0;
00725 
00726       if (System::getStackLevel(addresses[i],addr,fnc,lib)) {
00727         std::ostringstream ost;
00728         ost << "#" << std::setw(3) << std::setiosflags( std::ios::left ) << i-totalOffset+1;
00729         ost << std::hex << addr << std::dec << " " << fnc << "  [" << lib << "]" << std::endl;
00730         btrace += ost.str();
00731       }
00732     }
00733     free(addresses);
00734   }
00735   else {
00736     free(addresses);
00737     return false;
00738   }
00739 
00740   return true;
00741 }
00742 
00743 bool System::getStackLevel(void* addresses  __attribute__ ((unused)),
00744                            void*& addr      __attribute__ ((unused)),
00745                            std::string& fnc __attribute__ ((unused)),
00746                            std::string& lib __attribute__ ((unused)))
00747 {
00748 
00749 #ifdef __linux
00750 
00751   Dl_info info;
00752 
00753   if ( dladdr( addresses, &info ) && info.dli_fname
00754       && info.dli_fname[0] != '\0' ) {
00755     const char* symbol = info.dli_sname
00756     && info.dli_sname[0] != '\0' ? info.dli_sname : 0;
00757 
00758     lib = info.dli_fname;
00759     addr = info.dli_saddr;
00760     const char* dmg(0);
00761 
00762     if (symbol != 0) {
00763       int stat;
00764       dmg = abi::__cxa_demangle(symbol,0,0,&stat);
00765       fnc = (stat == 0) ? dmg : symbol;
00766     } else {
00767       fnc = "local";
00768     }
00769     free((void*)dmg);
00770     return true ;
00771   } else {
00772     return false ;
00773   }
00774 
00775 #else // not implemented for windows and osx
00776   return false ;
00777 #endif
00778 
00779 }
00780 
00782 int System::setEnv(const std::string &name, const std::string &value, int overwrite)
00783 {
00784 #ifndef WIN32
00785   // UNIX version
00786   return value.empty() ?
00787     // remove if set to nothing (and return success)
00788     ::unsetenv(name.c_str()) , 0 :
00789     // set the value
00790     ::setenv(name.c_str(),value.c_str(), overwrite);
00791 #else
00792   // Windows version
00793   if ( value.empty() ) {
00794     // equivalent to unsetenv
00795     return ::_putenv((name+"=").c_str());
00796   }
00797   else {
00798     if ( !getenv(name.c_str()) || overwrite ) {
00799       // set if not yet present or overwrite is set (force)
00800       return ::_putenv((name+"="+value).c_str());
00801     }
00802   }
00803   return 0; // if we get here, we are trying to set a variable already set, but
00804             // not to overwrite.
00805             // It is considered a success on Linux (man P setenv)
00806 #endif
00807 
00808 }

Generated at Mon Nov 24 14:38:47 2008 for Gaudi Framework, version v20r3 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004