The Gaudi Framework  master (37c0b60a)
ModuleInfo.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 //====================================================================
12 // ModuleInfo.cpp
13 //--------------------------------------------------------------------
14 //
15 // Package : System (The LHCb System service)
16 //
17 // Description: Implementation of Systems internals
18 //
19 // Author : M.Frank
20 // Created : 13/1/99
21 // Changes :
22 //====================================================================
23 #define SYSTEM_MODULEINFO_CPP
24 
25 // #include <ctime>
26 #include <cstdlib>
27 #include <cstring>
28 // #include <iostream>
29 // #include <typeinfo>
30 
31 #include <GaudiKernel/ModuleInfo.h>
32 #include <GaudiKernel/System.h>
33 
34 #ifdef _WIN32
35 # define NOMSG
36 # define NOGDI
37 # define strcasecmp _stricmp
38 # define strncasecmp _strnicmp
39 # include "Win32PsApi.h"
40 # include <process.h>
41 # include <windows.h>
42 static PsApiFunctions _psApi;
43 # define getpid _getpid
44 # undef NOMSG
45 # undef NOGDI
46 # ifndef PATH_MAX
47 # define PATH_MAX 1024
48 # endif
49 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
50 # include <cstdio>
51 # include <dlfcn.h>
52 # include <errno.h>
53 # include <libgen.h>
54 # include <string.h>
55 # include <sys/param.h>
56 # include <sys/times.h>
57 # include <unistd.h>
58 #endif
59 
60 static System::ImageHandle ModuleHandle = nullptr;
61 static std::vector<std::string> s_linkedModules;
62 
65  static std::string module( "" );
66  if ( module == "" ) {
67  if ( processHandle() && moduleHandle() ) {
68 #ifdef _WIN32
69  char moduleName[256] = { "Unknown.module" };
70  moduleName[0] = 0;
71  if ( _psApi ) {
72  _psApi.GetModuleBaseNameA( processHandle(), (HINSTANCE)moduleHandle(), moduleName, sizeof( moduleName ) );
73  }
75 #elif defined( __linux ) || defined( __APPLE__ )
76  std::string mod = ::basename( (char*)( (Dl_info*)moduleHandle() )->dli_fname );
77 #elif __hpux
78  std::string mod = ::basename( ( (HMODULE*)moduleHandle() )->dsc.filename );
79 #endif
80  module = mod.substr( 0, mod.rfind( '.' ) );
81  }
82  }
83  return module;
84 }
85 
88  static std::string module( "" );
89  if ( module == "" ) {
90  if ( processHandle() && moduleHandle() ) {
91  char name[PATH_MAX] = { "Unknown.module" };
92  name[0] = 0;
93 #ifdef _WIN32
94  if ( _psApi ) {
95  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)moduleHandle(), name, sizeof( name ) );
96  module = name;
97  }
98 #else
99  const char* path =
100 # if defined( __linux ) || defined( __APPLE__ )
101  ( (Dl_info*)moduleHandle() )->dli_fname;
102 # elif __hpux
103  ( (HMODULE*)moduleHandle() )->dsc.filename;
104 # endif
105  if ( ::realpath( path, name ) ) module = name;
106 #endif
107  }
108  }
109  return module;
110 }
111 
114  static ModuleType type = UNKNOWN;
115  if ( type == UNKNOWN ) {
116  const std::string& module = moduleNameFull();
117  size_t loc = module.rfind( '.' ) + 1;
118  if ( loc == 0 )
119  type = EXECUTABLE;
120  else if ( module[loc] == 'e' || module[loc] == 'E' )
121  type = EXECUTABLE;
122 #ifdef _WIN32
123  else if ( module[loc] == 'd' || module[loc] == 'D' )
124 #else
125  else if ( module[loc] == 's' && module[loc + 1] == 'o' )
126 #endif
127  type = SHAREDLIB;
128  else
129  type = UNKNOWN;
130  }
131  return type;
132 }
133 
136  static long pid = ::getpid();
137 #ifdef _WIN32
138  static HANDLE hP = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid );
139 #else
140  static void* hP = (void*)pid;
141 #endif
142  return hP;
143 }
144 
145 void System::setModuleHandle( System::ImageHandle handle ) { ModuleHandle = handle; }
146 
148  if ( !ModuleHandle ) {
149  if ( processHandle() ) {
150 #ifdef _WIN32
151  static HINSTANCE handle = 0;
152  DWORD cbNeeded;
153  if ( 0 == handle && _psApi ) {
154  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
155  }
156  return handle;
157 #elif defined( __linux ) || defined( __APPLE__ )
158  static Dl_info info;
159  if ( ::dladdr( reinterpret_cast<void*>( System::moduleHandle ), &info ) ) return &info;
160 #elif __hpux
161  return 0; // Don't know how to solve this .....
162 #endif
163  }
164  }
165  return ModuleHandle;
166 }
167 
169 #ifdef _WIN32
170  if ( processHandle() ) {
171  static HINSTANCE handle = 0;
172  DWORD cbNeeded;
173  if ( 0 == handle && _psApi ) {
174  if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof( ModuleHandle ), &cbNeeded ) ) {}
175  }
176  return handle;
177  }
178  return 0;
179 #elif defined( __linux ) || defined( __APPLE__ )
180  // This does NOT work!
181  static Dl_info infoBuf, *info = &infoBuf;
182  if ( !info ) {
183  void* handle = ::dlopen( nullptr, RTLD_LAZY );
184  // printf("Exe handle:%X\n", handle);
185  if ( handle ) {
186  void* func = ::dlsym( handle, "main" );
187  // printf("Exe:Func handle:%X\n", func);
188  if ( func ) {
189  if ( 0 != ::dladdr( func, &infoBuf ) ) {
190  // std::cout << "All OK" << std::endl;
191  info = &infoBuf;
192  }
193  }
194  }
195  }
196  return info;
197 #elif __hpux
198  // Don't know how to solve this .....
199  return 0;
200 #endif
201 }
202 
204  static std::string module( "" );
205  if ( module.length() == 0 ) {
206  char name[PATH_MAX] = { "Unknown.module" };
207  name[0] = 0;
208 #ifdef _WIN32
209  if ( _psApi && processHandle() ) {
210  _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name, sizeof( name ) );
211  module = name;
212  }
213 #elif defined( __linux ) || defined( __APPLE__ )
214  char cmd[512];
215  ::sprintf( cmd, "/proc/%d/exe", ::getpid() );
216  module = "Unknown";
217  if ( ::readlink( cmd, name, sizeof( name ) ) >= 0 ) module = name;
218 #elif __hpux
219  if ( ::realpath( ( (HMODULE*)exeHandle() )->dsc.filename, name ) ) module = name;
220 #endif
221  }
222  return module;
223 }
224 
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 ) { s_linkedModules.push_back( fname ); }
248  }
249  ::fclose( maps );
250 #endif
251  }
252  return s_linkedModules;
253 }
std::string
STL class.
AtlasMCRecoFullPrecedenceDump.path
path
Definition: AtlasMCRecoFullPrecedenceDump.py:49
System.h
std::vector< std::string >
std::string::length
T length(T... args)
System::moduleType
GAUDI_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:113
System::moduleNameFull
GAUDI_API const std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:87
System::ImageHandle
void * ImageHandle
Definition of an image handle.
Definition: ModuleInfo.h:40
System::processHandle
GAUDI_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:135
Win32PsApi.h
System::setModuleHandle
GAUDI_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:145
System::EXECUTABLE
@ EXECUTABLE
Definition: ModuleInfo.h:38
System::exeName
GAUDI_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:203
ModuleInfo.h
std::vector::push_back
T push_back(T... args)
Gaudi.CommonGaudiConfigurables.mod
mod
Definition: CommonGaudiConfigurables.py:39
cpluginsvc.func
func
Definition: cpluginsvc.py:235
Io::UNKNOWN
@ UNKNOWN
Definition: IFileMgr.h:156
System::moduleName
GAUDI_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:64
System::exeHandle
GAUDI_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:168
System::moduleHandle
GAUDI_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:147
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:225
System::ModuleType
ModuleType
Definition: ModuleInfo.h:38
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
root_map_dump.maps
maps
Definition: root_map_dump.py:72
System::SHAREDLIB
@ SHAREDLIB
Definition: ModuleInfo.h:38
GaudiKernel.Constants.FALSE
FALSE
Definition: Constants.py:38
std::string::rfind
T rfind(T... args)