All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ModuleInfo.cpp
Go to the documentation of this file.
1 //====================================================================
2 // ModuleInfo.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System (The LHCb System service)
6 //
7 // Description: Implementation of Systems internals
8 //
9 // Author : M.Frank
10 // Created : 13/1/99
11 // Changes :
12 //====================================================================
13 #define SYSTEM_MODULEINFO_CPP
14 
15 //#include <ctime>
16 #include <cstring>
17 #include <cstdlib>
18 //#include <iostream>
19 //#include <typeinfo>
20 
21 #include "GaudiKernel/ModuleInfo.h"
22 #include "GaudiKernel/System.h"
23 
24 #ifdef _WIN32
25  #define NOMSG
26  #define NOGDI
27  # define strcasecmp _stricmp
28  # define strncasecmp _strnicmp
29  #include "process.h"
30  #include "windows.h"
31  #include "Win32PsApi.h"
32 static PsApiFunctions _psApi;
33  #define getpid _getpid
34  #undef NOMSG
35  #undef NOGDI
36  #ifndef PATH_MAX
37  # define PATH_MAX 1024
38  #endif
39 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
40  #include <errno.h>
41  #include <string.h>
42  #include "sys/times.h"
43  #include "sys/param.h"
44  #include "unistd.h"
45  #include "libgen.h"
46  #include <cstdio>
47  #include <dlfcn.h>
48 #endif
49 
50 static System::ImageHandle ModuleHandle = nullptr;
51 static std::vector<std::string> s_linkedModules;
52 
55  static std::string module("");
56  if ( module == "" ) {
57  if ( processHandle() && moduleHandle() ) {
58 #ifdef _WIN32
59  char moduleName[256] = {"Unknown.module"};
60  moduleName[0] = 0;
61  if ( _psApi ) {
62  _psApi.GetModuleBaseNameA( processHandle(), (HINSTANCE)moduleHandle(), moduleName, sizeof(moduleName) );
63  }
65 #elif defined(__linux) || defined(__APPLE__)
66  std::string mod = ::basename((char*)((Dl_info*)moduleHandle())->dli_fname);
67 #elif __hpux
68  std::string mod = ::basename(((HMODULE*)moduleHandle())->dsc.filename);
69 #endif
70  module = mod.substr(0, mod.rfind('.'));
71  }
72  }
73  return module;
74 }
75 
78  static std::string module("");
79  if ( module == "" ) {
80  if ( processHandle() && moduleHandle() ) {
81  char name[PATH_MAX] = {"Unknown.module"};
82  name[0] = 0;
83 #ifdef _WIN32
84  if ( _psApi ) {
85  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)moduleHandle(), name,sizeof(name) );
86  module = name;
87  }
88 #else
89  const char *path =
90 # if defined(__linux) || defined(__APPLE__)
91  ((Dl_info*)moduleHandle())->dli_fname;
92 # elif __hpux
93  ((HMODULE*)moduleHandle())->dsc.filename;
94 # endif
95  if (::realpath(path, name))
96  module = name;
97 #endif
98  }
99  }
100  return module;
101 }
102 
105  static ModuleType type = UNKNOWN;
106  if ( type == UNKNOWN ) {
107  const std::string& module = moduleNameFull();
108  int loc = module.rfind('.')+1;
109  if ( loc == 0 )
110  type = EXECUTABLE;
111  else if ( module[loc] == 'e' || module[loc] == 'E' )
112  type = EXECUTABLE;
113 #ifdef _WIN32
114  else if ( module[loc] == 'd' || module[loc] == 'D' )
115 #else
116  else if ( module[loc] == 's' && module[loc+1] == 'o' )
117 #endif
118  type = SHAREDLIB;
119  else
120  type = UNKNOWN;
121  }
122  return type;
123 }
124 
127  static long pid = ::getpid();
128 #ifdef _WIN32
129  static HANDLE hP = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
130 #else
131  static void* hP = (void*)pid;
132 #endif
133  return hP;
134 }
135 
137  ModuleHandle = handle;
138 }
139 
141  if ( !ModuleHandle ) {
142  if ( processHandle() ) {
143 #ifdef _WIN32
144  static HINSTANCE handle = 0;
145  DWORD cbNeeded;
146  if ( 0 == handle && _psApi ) {
147  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
148  }
149  }
150  return handle;
151 #elif defined(__linux) || defined(__APPLE__)
152  static Dl_info info;
153  if ( 0 !=
154  ::dladdr(
155 #if __GNUC__ < 4
156  (void*)System::moduleHandle
157 #else
158  FuncPtrCast<void*>(System::moduleHandle)
159 #endif
160  , &info) ) {
161  return &info;
162  }
163 #elif __hpux
164  return 0; // Don't know how to solve this .....
165 #endif
166  }
167  }
168  return ModuleHandle;
169 }
170 
172 #ifdef _WIN32
173  if ( processHandle() ) {
174  static HINSTANCE handle = 0;
175  DWORD cbNeeded;
176  if ( 0 == handle && _psApi ) {
177  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
178  }
179  }
180  return handle;
181  }
182  return 0;
183 #elif defined(__linux) || defined(__APPLE__)
184  // This does NOT work!
185  static Dl_info infoBuf, *info = &infoBuf;
186  if ( !info ) {
187  void* handle = ::dlopen(nullptr, RTLD_LAZY);
188  //printf("Exe handle:%X\n", handle);
189  if ( handle ) {
190  void* func = ::dlsym(handle, "main");
191  //printf("Exe:Func handle:%X\n", func);
192  if ( func ) {
193  if ( 0 != ::dladdr(func, &infoBuf) ) {
194  //std::cout << "All OK" << std::endl;
195  info = &infoBuf;
196  }
197  }
198  }
199  }
200  return info;
201 #elif __hpux
202  // Don't know how to solve this .....
203  return 0;
204 #endif
205 }
206 
208  static std::string module("");
209  if ( module.length() == 0 ) {
210  char name[PATH_MAX] = {"Unknown.module"};
211  name[0] = 0;
212 #ifdef _WIN32
213  if ( _psApi && processHandle() ) {
214  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name,sizeof(name) );
215  module = name;
216  }
217 #elif defined(__linux) || defined(__APPLE__)
218  char cmd[512];
219  ::sprintf(cmd, "/proc/%d/exe", ::getpid());
220  module = "Unknown";
221  if (::readlink(cmd, name, sizeof(name)) >= 0)
222  module = name;
223 #elif __hpux
224  if (::realpath(((HMODULE*)exeHandle())->dsc.filename, name))
225  module = name;
226 #endif
227  }
228  return module;
229 }
230 
232  if ( s_linkedModules.size() == 0 ) {
233 #ifdef _WIN32
234  char name[255]; // Maximum file name length on NT 4.0
235  DWORD cbNeeded;
236  HINSTANCE handle[1024];
237  if ( _psApi ) {
238  if ( _psApi.EnumProcessModules(processHandle(),handle,sizeof(handle),&cbNeeded) ) {
239  for (size_t i = 0; i < cbNeeded/sizeof(HANDLE); i++ ) {
240  if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof(name)) ) {
241  s_linkedModules.push_back(name);
242  }
243  }
244  }
245  }
246 #elif defined(__linux) || defined(__APPLE__)
247  char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
248  ::sprintf(ff, "/proc/%d/maps", ::getpid());
249  FILE* maps = ::fopen(ff, "r");
250  while( ::fgets(cmd, sizeof(cmd), maps) ) {
251  int len;
252  sscanf(cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname);
253  if ( len > 0 && strncmp(buf2,"r-xp",strlen("r-xp")) == 0 ) {
254  s_linkedModules.push_back(fname);
255  }
256  }
257  ::fclose(maps);
258 #endif
259  }
260  return s_linkedModules;
261 }
GAUDI_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:104
GAUDI_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:136
GAUDI_API const std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:77
T rfind(T...args)
GAUDI_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:126
void * ImageHandle
Definition of an image handle.
Definition: ModuleInfo.h:30
STL class.
GAUDI_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:207
T push_back(T...args)
ModuleType
Definition: ModuleInfo.h:28
GAUDI_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:140
GAUDI_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:171
GAUDI_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:231
T length(T...args)
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:54
T substr(T...args)