Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
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 <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  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 ) ) module = name;
96 #endif
97  }
98  }
99  return module;
100 }
101 
104  static ModuleType type = UNKNOWN;
105  if ( type == UNKNOWN ) {
106  const std::string& module = moduleNameFull();
107  int loc = module.rfind( '.' ) + 1;
108  if ( loc == 0 )
109  type = EXECUTABLE;
110  else if ( module[loc] == 'e' || module[loc] == 'E' )
111  type = EXECUTABLE;
112 #ifdef _WIN32
113  else if ( module[loc] == 'd' || module[loc] == 'D' )
114 #else
115  else if ( module[loc] == 's' && module[loc + 1] == 'o' )
116 #endif
117  type = SHAREDLIB;
118  else
119  type = UNKNOWN;
120  }
121  return type;
122 }
123 
126  static long pid = ::getpid();
127 #ifdef _WIN32
128  static HANDLE hP = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
129 #else
130  static void* hP = (void*)pid;
131 #endif
132  return hP;
133 }
134 
135 void System::setModuleHandle( System::ImageHandle handle ) { ModuleHandle = handle; }
136 
138  if ( !ModuleHandle ) {
139  if ( processHandle() ) {
140 #ifdef _WIN32
141  static HINSTANCE handle = 0;
142  DWORD cbNeeded;
143  if ( 0 == handle && _psApi ) {
144  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
145  }
146  return handle;
147 #elif defined( __linux ) || defined( __APPLE__ )
148  static Dl_info info;
149  if ( ::dladdr( reinterpret_cast<void*>( System::moduleHandle ), &info ) ) return &info;
150 #elif __hpux
151  return 0; // Don't know how to solve this .....
152 #endif
153  }
154  }
155  return ModuleHandle;
156 }
157 
159 #ifdef _WIN32
160  if ( processHandle() ) {
161  static HINSTANCE handle = 0;
162  DWORD cbNeeded;
163  if ( 0 == handle && _psApi ) {
164  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
165  }
166  return handle;
167  }
168  return 0;
169 #elif defined( __linux ) || defined( __APPLE__ )
170  // This does NOT work!
171  static Dl_info infoBuf, *info = &infoBuf;
172  if ( !info ) {
173  void* handle = ::dlopen( nullptr, RTLD_LAZY );
174  // printf("Exe handle:%X\n", handle);
175  if ( handle ) {
176  void* func = ::dlsym( handle, "main" );
177  // printf("Exe:Func handle:%X\n", func);
178  if ( func ) {
179  if ( 0 != ::dladdr( func, &infoBuf ) ) {
180  // std::cout << "All OK" << std::endl;
181  info = &infoBuf;
182  }
183  }
184  }
185  }
186  return info;
187 #elif __hpux
188  // Don't know how to solve this .....
189  return 0;
190 #endif
191 }
192 
194  static std::string module( "" );
195  if ( module.length() == 0 ) {
196  char name[PATH_MAX] = {"Unknown.module"};
197  name[0] = 0;
198 #ifdef _WIN32
199  if ( _psApi && processHandle() ) {
200  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name, sizeof( name ) );
201  module = name;
202  }
203 #elif defined( __linux ) || defined( __APPLE__ )
204  char cmd[512];
205  ::sprintf( cmd, "/proc/%d/exe", ::getpid() );
206  module = "Unknown";
207  if ( ::readlink( cmd, name, sizeof( name ) ) >= 0 ) module = name;
208 #elif __hpux
209  if ( ::realpath( ( (HMODULE*)exeHandle() )->dsc.filename, name ) ) module = name;
210 #endif
211  }
212  return module;
213 }
214 
216  if ( s_linkedModules.size() == 0 ) {
217 #ifdef _WIN32
218  char name[255]; // Maximum file name length on NT 4.0
219  DWORD cbNeeded;
220  HINSTANCE handle[1024];
221  if ( _psApi ) {
222  if ( _psApi.EnumProcessModules( processHandle(), handle, sizeof( handle ), &cbNeeded ) ) {
223  for ( size_t i = 0; i < cbNeeded / sizeof( HANDLE ); i++ ) {
224  if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof( name ) ) ) {
225  s_linkedModules.push_back( name );
226  }
227  }
228  }
229  }
230 #elif defined( __linux ) || defined( __APPLE__ )
231  char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
232  ::sprintf( ff, "/proc/%d/maps", ::getpid() );
233  FILE* maps = ::fopen( ff, "r" );
234  while ( ::fgets( cmd, sizeof( cmd ), maps ) ) {
235  int len;
236  sscanf( cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname );
237  if ( len > 0 && strncmp( buf2, "r-xp", strlen( "r-xp" ) ) == 0 ) { s_linkedModules.push_back( fname ); }
238  }
239  ::fclose( maps );
240 #endif
241  }
242  return s_linkedModules;
243 }
GAUDI_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:103
GAUDI_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:135
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:125
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:193
T push_back(T...args)
ModuleType
Definition: ModuleInfo.h:28
GAUDI_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:137
GAUDI_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:158
GAUDI_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:215
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)