00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define SYSTEM_MODULEINFO_CPP
00015
00016
00017 #include <cstring>
00018 #include <cstdlib>
00019
00020
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 module = name;
00088 }
00089 #else
00090 const char *path =
00091 # if defined(linux) || defined(__APPLE__)
00092 ((Dl_info*)moduleHandle())->dli_fname;
00093 # elif __hpux
00094 ((HMODULE*)moduleHandle())->dsc.filename;
00095 # endif
00096 if (::realpath(path, name))
00097 module = name;
00098 #endif
00099 }
00100 }
00101 return module;
00102 }
00103
00105 System::ModuleType System::moduleType() {
00106 static ModuleType type = UNKNOWN;
00107 if ( type == UNKNOWN ) {
00108 const std::string& module = moduleNameFull();
00109 int loc = module.rfind('.')+1;
00110 if ( loc == 0 )
00111 type = EXECUTABLE;
00112 else if ( module[loc] == 'e' || module[loc] == 'E' )
00113 type = EXECUTABLE;
00114 #ifdef _WIN32
00115 else if ( module[loc] == 'd' || module[loc] == 'D' )
00116 #else
00117 else if ( module[loc] == 's' && module[loc+1] == 'o' )
00118 #endif
00119 type = SHAREDLIB;
00120 else
00121 type = UNKNOWN;
00122 }
00123 return type;
00124 }
00125
00127 void* System::processHandle() {
00128 static long pid = ::getpid();
00129 #ifdef _WIN32
00130 static HANDLE hP = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
00131 #else
00132 static void* hP = (void*)pid;
00133 #endif
00134 return hP;
00135 }
00136
00137 void System::setModuleHandle(System::ImageHandle handle) {
00138 ModuleHandle = handle;
00139 }
00140
00141 System::ImageHandle System::moduleHandle() {
00142 if ( 0 == ModuleHandle ) {
00143 if ( processHandle() ) {
00144 #ifdef _WIN32
00145 static HINSTANCE handle = 0;
00146 DWORD cbNeeded;
00147 if ( 0 == handle && _psApi.isValid() ) {
00148 if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
00149 }
00150 }
00151 return handle;
00152 #elif defined(linux) || defined(__APPLE__)
00153 static Dl_info info;
00154 if ( 0 !=
00155 ::dladdr(
00156 #if __GNUC__ < 4
00157 (void*)System::moduleHandle
00158 #else
00159 FuncPtrCast<void*>(System::moduleHandle)
00160 #endif
00161 , &info) ) {
00162 return &info;
00163 }
00164 #elif __hpux
00165 return 0;
00166 #endif
00167 }
00168 }
00169 return ModuleHandle;
00170 }
00171
00172 System::ImageHandle System::exeHandle() {
00173 #ifdef _WIN32
00174 if ( processHandle() ) {
00175 static HINSTANCE handle = 0;
00176 DWORD cbNeeded;
00177 if ( 0 == handle && _psApi.isValid() ) {
00178 if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
00179 }
00180 }
00181 return handle;
00182 }
00183 return 0;
00184 #elif defined(linux) || defined(__APPLE__)
00185
00186 static Dl_info infoBuf, *info = &infoBuf;
00187 if ( 0 == info ) {
00188 void* handle = ::dlopen(0, RTLD_LAZY);
00189
00190 if ( 0 != handle ) {
00191 void* func = ::dlsym(handle, "main");
00192
00193 if ( 0 != func ) {
00194 if ( 0 != ::dladdr(func, &infoBuf) ) {
00195
00196 info = &infoBuf;
00197 }
00198 }
00199 }
00200 }
00201 return info;
00202 #elif __hpux
00203
00204 return 0;
00205 #endif
00206 }
00207
00208 const std::string& System::exeName() {
00209 static std::string module("");
00210 if ( module.length() == 0 ) {
00211 char name[PATH_MAX] = {"Unknown.module"};
00212 name[0] = 0;
00213 #ifdef _WIN32
00214 if ( _psApi.isValid() && processHandle() ) {
00215 _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name,sizeof(name) );
00216 module = name;
00217 }
00218 #elif defined(linux) || defined(__APPLE__)
00219 char cmd[512];
00220 ::sprintf(cmd, "/proc/%d/exe", ::getpid());
00221 module = "Unknown";
00222 if (::readlink(cmd, name, sizeof(name)) >= 0)
00223 module = name;
00224 #elif __hpux
00225 if (::realpath(((HMODULE*)exeHandle())->dsc.filename, name))
00226 module = name;
00227 #endif
00228 }
00229 return module;
00230 }
00231
00232 const std::vector<std::string> System::linkedModules() {
00233 if ( s_linkedModules.size() == 0 ) {
00234 #ifdef _WIN32
00235 char name[255];
00236 DWORD cbNeeded;
00237 HINSTANCE handle[1024];
00238 if ( _psApi.isValid() ) {
00239 if ( _psApi.EnumProcessModules(processHandle(),handle,sizeof(handle),&cbNeeded) ) {
00240 for (size_t i = 0; i < cbNeeded/sizeof(HANDLE); i++ ) {
00241 if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof(name)) ) {
00242 s_linkedModules.push_back(name);
00243 }
00244 }
00245 }
00246 }
00247 #elif defined(linux) || defined(__APPLE__)
00248 char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
00249 ::sprintf(ff, "/proc/%d/maps", ::getpid());
00250 FILE* maps = ::fopen(ff, "r");
00251 while( ::fgets(cmd, sizeof(cmd), maps) ) {
00252 int len;
00253 sscanf(cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname);
00254 if ( len > 0 && strncmp(buf2,"r-xp",strlen("r-xp")) == 0 ) {
00255 s_linkedModules.push_back(fname);
00256 }
00257 }
00258 ::fclose(maps);
00259 #endif
00260 }
00261 return s_linkedModules;
00262 }