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