| # Gaudi Framework, version v21r7p1 |

Home |  | Generated: 15 Feb 2010

# ModuleInfo.cpp

Go to the documentation of this file.

    00001 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/src/Lib/ModuleInfo.cpp,v 1.10 2008/10/28 10:40:19 marcocle Exp $
    00002 //====================================================================
    00003 //      ModuleInfo.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_MODULEINFO_CPP
    00015
    00016 //#include <ctime>
    00017 #include <cstring>
    00018 #include <cstdlib>
    00019 //#include <iostream>
    00020 //#include <typeinfo>
    00021
    00022 #include "GaudiKernel/ModuleInfo.h"
    00023 #include "GaudiKernel/System.h"
    00024
    00025 #ifdef _WIN32
    00026   #define NOMSG
    00027   #define NOGDI
    00028   #  define strcasecmp _stricmp
    00029   #  define strncasecmp _strnicmp
    00030   #include "process.h"
    00031   #include "windows.h"
    00032   #include "Win32PsApi.h"
    00033 static PsApiFunctions _psApi;
    00034   #define getpid _getpid
    00035   #undef NOMSG
    00036   #undef NOGDI
    00037   #ifndef PATH_MAX
    00038   #  define PATH_MAX 1024
    00039   #endif
    00040 #else  // UNIX...: first the EGCS stuff, then the OS dependent includes
    00041   #include <errno.h>
    00042   #include <string.h>
    00043   #include "sys/times.h"
    00044   #include "sys/param.h"
    00045   #include "unistd.h"
    00046   #include "libgen.h"
    00047   #include <cstdio>
    00048   #include <dlfcn.h>
    00049 #endif
    00050
    00051 static System::ImageHandle      ModuleHandle = 0;
    00052 static std::vector<std::string> s_linkedModules;
    00053
    00055 const std::string& System::moduleName()   {
    00056   static std::string module("");
    00057   if ( module == "" )   {
    00058     if ( processHandle() && moduleHandle() )    {
    00059 #ifdef _WIN32
    00060       char moduleName[256] = {"Unknown.module"};
    00061       moduleName[0] = 0;
    00062       if ( _psApi.isValid() )   {
    00063         _psApi.GetModuleBaseNameA( processHandle(), (HINSTANCE)moduleHandle(), moduleName, sizeof(moduleName) );
    00064       }
    00065       std::string mod = moduleName;
    00066 #elif defined(linux) || defined(__APPLE__)
    00067       std::string mod = ::basename((char*)((Dl_info*)moduleHandle())->dli_fname);
    00068 #elif __hpux
    00069       std::string mod = ::basename(((HMODULE*)moduleHandle())->dsc.filename);
    00070 #endif
    00071       module = mod.substr(0, mod.rfind('.'));
    00072     }
    00073   }
    00074   return module;
    00075 }
    00076
    00078 const std::string& System::moduleNameFull()   {
    00079   static std::string module("");
    00080   if ( module == "" )   {
    00081     if ( processHandle() && moduleHandle() )    {
    00082       char name[PATH_MAX] = {"Unknown.module"};
    00083       name[0] = 0;
    00084 #ifdef _WIN32
    00085       if ( _psApi.isValid() )   {
    00086         _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)moduleHandle(), name,sizeof(name) );
    00087       }
    00088 #elif defined(linux) || defined(__APPLE__)
    00089       ::realpath(((Dl_info*)moduleHandle())->dli_fname, name);
    00090 #elif __hpux
    00091       ::realpath(((HMODULE*)moduleHandle())->dsc.filename, name);
    00092 #endif
    00093       module = name;
    00094     }
    00095   }
    00096   return module;
    00097 }
    00098
    00100 System::ModuleType System::moduleType()   {
    00101   static ModuleType type = UNKNOWN;
    00102   if ( type == UNKNOWN )    {
    00103     const std::string& module = moduleNameFull();
    00104     int loc = module.rfind('.')+1;
    00105     if ( loc == 0 )
    00106       type = EXECUTABLE;
    00107     else if ( module[loc] == 'e' || module[loc] == 'E' )
    00108       type = EXECUTABLE;
    00109 #ifdef _WIN32
    00110     else if ( module[loc] == 'd' || module[loc] == 'D' )
    00111 #else
    00112     else if ( module[loc] == 's' && module[loc+1] == 'o' )
    00113 #endif
    00114       type = SHAREDLIB;
    00115     else
    00116       type = UNKNOWN;
    00117   }
    00118   return type;
    00119 }
    00120
    00122 void* System::processHandle()   {
    00123   static long pid = ::getpid();
    00124 #ifdef _WIN32
    00125   static HANDLE hP = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
    00126 #else
    00127   static void* hP = (void*)pid;
    00128 #endif
    00129   return hP;
    00130 }
    00131
    00132 void System::setModuleHandle(System::ImageHandle handle)    {
    00133   ModuleHandle = handle;
    00134 }
    00135
    00136 System::ImageHandle System::moduleHandle()    {
    00137   if ( 0 == ModuleHandle )    {
    00138     if ( processHandle() )    {
    00139 #ifdef _WIN32
    00140       static HINSTANCE handle = 0;
    00141       DWORD   cbNeeded;
    00142       if ( 0 == handle && _psApi.isValid() )    {
    00143         if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) )   {
    00144         }
    00145       }
    00146       return handle;
    00147 #elif defined(linux) || defined(__APPLE__)
    00148       static Dl_info info;
    00149       if ( 0 !=
    00150            ::dladdr(
    00151 #if __GNUC__ < 4
    00152                (void*)System::moduleHandle
    00153 #else
    00154                FuncPtrCast<void*>(System::moduleHandle)
    00155 #endif
    00156                , &info) ) {
    00157         return &info;
    00158       }
    00159 #elif __hpux
    00160       return 0;  // Don't know how to solve this .....
    00161 #endif
    00162     }
    00163   }
    00164   return ModuleHandle;
    00165 }
    00166
    00167 System::ImageHandle System::exeHandle()    {
    00168 #ifdef _WIN32
    00169   if ( processHandle() )    {
    00170     static HINSTANCE handle = 0;
    00171     DWORD   cbNeeded;
    00172     if ( 0 == handle && _psApi.isValid() )    {
    00173       if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) )   {
    00174       }
    00175     }
    00176     return handle;
    00177   }
    00178 #elif defined(linux) || defined(__APPLE__)
    00179   // This does NOT work!
    00180   static Dl_info infoBuf, *info = &infoBuf;
    00181   if ( 0 == info ) {
    00182     void* handle = ::dlopen(0, RTLD_LAZY);
    00183     //printf("Exe handle:%X\n", handle);
    00184     if ( 0 != handle ) {
    00185       void* func = ::dlsym(handle, "main");
    00186       //printf("Exe:Func handle:%X\n", func);
    00187       if ( 0 != func ) {
    00188         if ( 0 != ::dladdr(func, &infoBuf) ) {
    00189                 //std::cout << "All OK" << std::endl;
    00190           info = &infoBuf;
    00191         }
    00192       }
    00193     }
    00194   }
    00195   return info;
    00196 #elif __hpux
    00197   // Don't know how to solve this .....
    00198 #endif
    00199   return 0;
    00200 }
    00201
    00202 const std::string& System::exeName()    {
    00203   static std::string module("");
    00204   if ( module.length() == 0 )    {
    00205     char name[PATH_MAX] = {"Unknown.module"};
    00206     name[0] = 0;
    00207 #ifdef _WIN32
    00208     if ( _psApi.isValid() && processHandle() )   {
    00209       _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name,sizeof(name) );
    00210     }
    00211 #elif defined(linux) || defined(__APPLE__)
    00212     char cmd[512];
    00213     ::sprintf(cmd, "/proc/%d/exe", ::getpid());
    00214     module = "Unknown";
    00215     ::readlink(cmd, name, sizeof(name));
    00216 #elif __hpux
    00217     ::realpath(((HMODULE*)exeHandle())->dsc.filename, name);
    00218 #endif
    00219     module = name;
    00220   }
    00221   return module;
    00222 }
    00223
    00224 const std::vector<std::string> System::linkedModules()    {
    00225   if ( s_linkedModules.size() == 0 )    {
    00226 #ifdef _WIN32
    00227     char   name[255];  // Maximum file name length on NT 4.0
    00228     DWORD  cbNeeded;
    00229     HINSTANCE handle[1024];
    00230     if ( _psApi.isValid() )    {
    00231       if ( _psApi.EnumProcessModules(processHandle(),handle,sizeof(handle),&cbNeeded) )   {
    00232         for (size_t i = 0; i < cbNeeded/sizeof(HANDLE); i++ )    {
    00233           if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof(name)) )   {
    00234             s_linkedModules.push_back(name);
    00235           }
    00236         }
    00237       }
    00238     }
    00239 #elif defined(linux) || defined(__APPLE__)
    00240     char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
    00241     ::sprintf(ff, "/proc/%d/maps", ::getpid());
    00242     FILE* maps = ::fopen(ff, "r");
    00243     while( ::fgets(cmd, sizeof(cmd), maps) ) {
    00244       int len;
    00245       sscanf(cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname);
    00246       if ( len > 0 && strncmp(buf2,"r-xp",strlen("r-xp")) == 0 ) {
    00247         s_linkedModules.push_back(fname);
    00248       }
    00249     }
    00250     ::fclose(maps);
    00251 #endif
    00252   }
    00253   return s_linkedModules;
    00254 }