The Gaudi Framework  v30r3 (a5ef0a68)
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 (::dladdr( reinterpret_cast<void*>( System::moduleHandle ), &info ) ) return &info;
156 #elif __hpux
157  return 0; // Don't know how to solve this .....
158 #endif
159  }
160  }
161  return ModuleHandle;
162 }
163 
165 {
166 #ifdef _WIN32
167  if ( processHandle() ) {
168  static HINSTANCE handle = 0;
169  DWORD cbNeeded;
170  if ( 0 == handle && _psApi ) {
171  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {
172  }
173  }
174  return handle;
175  }
176  return 0;
177 #elif defined( __linux ) || defined( __APPLE__ )
178  // This does NOT work!
179  static Dl_info infoBuf, *info = &infoBuf;
180  if ( !info ) {
181  void* handle = ::dlopen( nullptr, RTLD_LAZY );
182  // printf("Exe handle:%X\n", handle);
183  if ( handle ) {
184  void* func = ::dlsym( handle, "main" );
185  // printf("Exe:Func handle:%X\n", func);
186  if ( func ) {
187  if ( 0 != ::dladdr( func, &infoBuf ) ) {
188  // std::cout << "All OK" << std::endl;
189  info = &infoBuf;
190  }
191  }
192  }
193  }
194  return info;
195 #elif __hpux
196  // Don't know how to solve this .....
197  return 0;
198 #endif
199 }
200 
202 {
203  static std::string module( "" );
204  if ( module.length() == 0 ) {
205  char name[PATH_MAX] = {"Unknown.module"};
206  name[0] = 0;
207 #ifdef _WIN32
208  if ( _psApi && processHandle() ) {
209  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name, sizeof( name ) );
210  module = name;
211  }
212 #elif defined( __linux ) || defined( __APPLE__ )
213  char cmd[512];
214  ::sprintf( cmd, "/proc/%d/exe", ::getpid() );
215  module = "Unknown";
216  if (::readlink( cmd, name, sizeof( name ) ) >= 0 ) module = name;
217 #elif __hpux
218  if (::realpath( ( (HMODULE*)exeHandle() )->dsc.filename, name ) ) module = name;
219 #endif
220  }
221  return module;
222 }
223 
225 {
226  if ( s_linkedModules.size() == 0 ) {
227 #ifdef _WIN32
228  char name[255]; // Maximum file name length on NT 4.0
229  DWORD cbNeeded;
230  HINSTANCE handle[1024];
231  if ( _psApi ) {
232  if ( _psApi.EnumProcessModules( processHandle(), handle, sizeof( handle ), &cbNeeded ) ) {
233  for ( size_t i = 0; i < cbNeeded / sizeof( HANDLE ); i++ ) {
234  if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof( name ) ) ) {
235  s_linkedModules.push_back( name );
236  }
237  }
238  }
239  }
240 #elif defined( __linux ) || defined( __APPLE__ )
241  char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
242  ::sprintf( ff, "/proc/%d/maps", ::getpid() );
243  FILE* maps = ::fopen( ff, "r" );
244  while (::fgets( cmd, sizeof( cmd ), maps ) ) {
245  int len;
246  sscanf( cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname );
247  if ( len > 0 && strncmp( buf2, "r-xp", strlen( "r-xp" ) ) == 0 ) {
248  s_linkedModules.push_back( fname );
249  }
250  }
251  ::fclose( maps );
252 #endif
253  }
254  return s_linkedModules;
255 }
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:201
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:164
GAUDI_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:224
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)