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