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