The Gaudi Framework  v40r0 (475e45c1)
ModuleInfo.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include <GaudiKernel/ModuleInfo.h>
12 #include <GaudiKernel/System.h>
13 #include <cstdlib>
14 #include <cstring>
15 
16 #ifdef _WIN32
17 # define NOMSG
18 # define NOGDI
19 # define strcasecmp _stricmp
20 # define strncasecmp _strnicmp
21 # include "Win32PsApi.h"
22 # include <process.h>
23 # include <windows.h>
24 static PsApiFunctions _psApi;
25 # define getpid _getpid
26 # undef NOMSG
27 # undef NOGDI
28 # ifndef PATH_MAX
29 # define PATH_MAX 1024
30 # endif
31 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
32 # include <cstdio>
33 # include <dlfcn.h>
34 # include <libgen.h>
35 # include <string.h>
36 # include <sys/param.h>
37 # include <sys/times.h>
38 # include <unistd.h>
39 #endif
40 
41 static System::ImageHandle ModuleHandle = nullptr;
42 static std::vector<std::string> s_linkedModules;
43 
45 const std::string& System::moduleName() {
46  static std::string module( "" );
47  if ( module == "" ) {
48  if ( processHandle() && moduleHandle() ) {
49 #ifdef _WIN32
50  char moduleName[256] = { "Unknown.module" };
51  moduleName[0] = 0;
52  if ( _psApi ) {
53  _psApi.GetModuleBaseNameA( processHandle(), (HINSTANCE)moduleHandle(), moduleName, sizeof( moduleName ) );
54  }
55  std::string mod = moduleName;
56 #elif defined( __linux ) || defined( __APPLE__ )
57  std::string mod = ::basename( (char*)( (Dl_info*)moduleHandle() )->dli_fname );
58 #elif __hpux
59  std::string mod = ::basename( ( (HMODULE*)moduleHandle() )->dsc.filename );
60 #endif
61  module = mod.substr( 0, mod.rfind( '.' ) );
62  }
63  }
64  return module;
65 }
66 
68 const std::string& System::moduleNameFull() {
69  static std::string module( "" );
70  if ( module == "" ) {
71  if ( processHandle() && moduleHandle() ) {
72  char name[PATH_MAX] = { "Unknown.module" };
73  name[0] = 0;
74 #ifdef _WIN32
75  if ( _psApi ) {
76  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)moduleHandle(), name, sizeof( name ) );
77  module = name;
78  }
79 #else
80 
81 # if defined( __linux ) || defined( __APPLE__ )
82  const char* path = ( (Dl_info*)moduleHandle() )->dli_fname;
83 # elif __hpux
84  const char* path = ( (HMODULE*)moduleHandle() )->dsc.filename;
85 # endif
86  if ( ::realpath( path, name ) ) module = name;
87 #endif
88  }
89  }
90  return module;
91 }
92 
95  static ModuleType type = UNKNOWN;
96  if ( type == UNKNOWN ) {
97  const std::string& module = moduleNameFull();
98  size_t loc = module.rfind( '.' ) + 1;
99  if ( loc == 0 )
100  type = EXECUTABLE;
101  else if ( module[loc] == 'e' || module[loc] == 'E' )
102  type = EXECUTABLE;
103 #ifdef _WIN32
104  else if ( module[loc] == 'd' || module[loc] == 'D' )
105 #else
106  else if ( module[loc] == 's' && module[loc + 1] == 'o' )
107 #endif
108  type = SHAREDLIB;
109  else
110  type = UNKNOWN;
111  }
112  return type;
113 }
114 
117  static long pid = ::getpid();
118 #ifdef _WIN32
119  static HANDLE hP = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
120 #else
121  static void* hP = (void*)pid;
122 #endif
123  return hP;
124 }
125 
126 void System::setModuleHandle( System::ImageHandle handle ) { ModuleHandle = handle; }
127 
129  if ( !ModuleHandle ) {
130  if ( processHandle() ) {
131 #ifdef _WIN32
132  static HINSTANCE handle = 0;
133  DWORD cbNeeded;
134  if ( 0 == handle && _psApi ) {
135  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
136  }
137  return handle;
138 #elif defined( __linux ) || defined( __APPLE__ )
139  static Dl_info info;
140  if ( ::dladdr( reinterpret_cast<void*>( System::moduleHandle ), &info ) ) return &info;
141 #elif __hpux
142  return 0; // Don't know how to solve this .....
143 #endif
144  }
145  }
146  return ModuleHandle;
147 }
148 
150 #ifdef _WIN32
151  if ( processHandle() ) {
152  static HINSTANCE handle = 0;
153  DWORD cbNeeded;
154  if ( 0 == handle && _psApi ) {
155  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
156  }
157  return handle;
158  }
159  return 0;
160 #elif defined( __linux ) || defined( __APPLE__ )
161  // This does NOT work!
162  static Dl_info infoBuf, *info = &infoBuf;
163  if ( !info ) {
164  void* handle = ::dlopen( nullptr, RTLD_LAZY );
165  // printf("Exe handle:%X\n", handle);
166  if ( handle ) {
167  void* func = ::dlsym( handle, "main" );
168  // printf("Exe:Func handle:%X\n", func);
169  if ( func ) {
170  if ( 0 != ::dladdr( func, &infoBuf ) ) {
171  // std::cout << "All OK" << std::endl;
172  info = &infoBuf;
173  }
174  }
175  }
176  }
177  return info;
178 #elif __hpux
179  // Don't know how to solve this .....
180  return 0;
181 #endif
182  return 0;
183 }
184 
185 const std::string& System::exeName() {
186  static std::string module( "" );
187  if ( module.length() == 0 ) {
188  char name[PATH_MAX] = { "Unknown.module" };
189  name[0] = 0;
190 #ifdef _WIN32
191  if ( _psApi && processHandle() ) {
192  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name, sizeof( name ) );
193  module = name;
194  }
195 #elif defined( __linux ) || defined( __APPLE__ )
196  char cmd[512];
197  ::sprintf( cmd, "/proc/%d/exe", ::getpid() );
198  module = "Unknown";
199  if ( ::readlink( cmd, name, sizeof( name ) ) >= 0 ) module = name;
200 #elif __hpux
201  if ( ::realpath( ( (HMODULE*)exeHandle() )->dsc.filename, name ) ) module = name;
202 #endif
203  }
204  return module;
205 }
206 
207 const std::vector<std::string> System::linkedModules() {
208  if ( s_linkedModules.size() == 0 ) {
209 #ifdef _WIN32
210  char name[255]; // Maximum file name length on NT 4.0
211  DWORD cbNeeded;
212  HINSTANCE handle[1024];
213  if ( _psApi ) {
214  if ( _psApi.EnumProcessModules( processHandle(), handle, sizeof( handle ), &cbNeeded ) ) {
215  for ( size_t i = 0; i < cbNeeded / sizeof( HANDLE ); i++ ) {
216  if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof( name ) ) ) {
217  s_linkedModules.push_back( name );
218  }
219  }
220  }
221  }
222 #elif defined( __linux ) || defined( __APPLE__ )
223  char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
224  ::sprintf( ff, "/proc/%d/maps", ::getpid() );
225  FILE* maps = ::fopen( ff, "r" );
226  while ( ::fgets( cmd, sizeof( cmd ), maps ) ) {
227  int len;
228  sscanf( cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname );
229  if ( len > 0 && strncmp( buf2, "r-xp", strlen( "r-xp" ) ) == 0 ) { s_linkedModules.push_back( fname ); }
230  }
231  ::fclose( maps );
232 #endif
233  }
234  return s_linkedModules;
235 }
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
System.h
System::moduleType
GAUDI_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:94
System::moduleNameFull
GAUDI_API const std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:68
System::ImageHandle
void * ImageHandle
Definition of an image handle.
Definition: ModuleInfo.h:25
System::processHandle
GAUDI_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:116
Win32PsApi.h
System::setModuleHandle
GAUDI_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:126
System::EXECUTABLE
@ EXECUTABLE
Definition: ModuleInfo.h:23
System::exeName
GAUDI_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:185
ModuleInfo.h
Gaudi.CommonGaudiConfigurables.mod
mod
Definition: CommonGaudiConfigurables.py:39
cpluginsvc.func
func
Definition: cpluginsvc.py:235
Io::UNKNOWN
@ UNKNOWN
Definition: IFileMgr.h:147
System::moduleName
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:45
System::exeHandle
GAUDI_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:149
System::moduleHandle
GAUDI_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:128
gaudirun.type
type
Definition: gaudirun.py:160
System::linkedModules
GAUDI_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:207
System::ModuleType
ModuleType
Definition: ModuleInfo.h:23
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
System::SHAREDLIB
@ SHAREDLIB
Definition: ModuleInfo.h:23
GaudiKernel.Constants.FALSE
FALSE
Definition: Constants.py:38