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