Elements  5.12.0
A C++ base framework for the Euclid Software.
ModuleInfo.cpp
Go to the documentation of this file.
1 
23 
24 #include <sys/times.h>
25 #include <sys/param.h>
26 #include <unistd.h>
27 #include <libgen.h>
28 #include <dlfcn.h>
29 
30 #ifdef __APPLE__
31 #include <mach-o/dyld.h> // for _NSGetExecutablePath
32 #endif
33 
34 #include <cstring>
35 #include <cstdlib>
36 #include <sstream> // for stringstream
37 #include <fstream> // for ifstream
38 #include <iostream>
39 #include <cerrno>
40 #include <cstdio>
41 #include <string> // for string
42 #include <vector>
43 
44 #ifdef __APPLE__
45 #include <climits> // for PATH_MAX
46 #endif
47 
48 #include <boost/filesystem/operations.hpp> // for filesystem::exists, canonical
49 
51 #include "ElementsKernel/Path.h" // for Path::Item
52 
53 using std::string;
54 using std::vector;
55 
56 namespace {
57  vector<string> s_linkedModules;
58 }
59 
60 namespace Elements {
61 namespace System {
62 
63 ModuleInfo::ModuleInfo() : m_dlinfo{nullptr} {
64 }
65 
66 ModuleInfo::ModuleInfo(void *funct) {
67  m_dlinfo.reset(new Dl_info);
68  ::dladdr(FuncPtrCast<void*>(funct), m_dlinfo.get());
69 }
70 
71 const string ModuleInfo::name() const {
72  return ::basename(const_cast<char*>(m_dlinfo->dli_fname));
73 }
74 
75 const string ModuleInfo::libraryName() const {
76  return const_cast<char*>(m_dlinfo->dli_fname);
77 }
78 
79 const void* ModuleInfo::addresse() const {
80  return m_dlinfo->dli_saddr;
81 }
82 
83 bool ModuleInfo::isEmpty() const {
84  return (m_dlinfo == nullptr);
85 }
86 
87 ModuleInfo::operator const Dl_info&() const {
88  return *m_dlinfo;
89 }
90 
91 namespace {
92  ImageHandle s_module_handle = nullptr;
93 }
95 const string& moduleName() {
96  static string module("");
97  if (module == "") {
98  if ( processHandle() and moduleHandle() ) {
99  string mod = ::basename(const_cast<char *>((reinterpret_cast<Dl_info*>(moduleHandle()))->dli_fname));
100  module = mod.substr(static_cast<string::size_type>(0), mod.find('.'));
101  }
102  }
103  return module;
104 }
105 
107 const string& moduleNameFull() {
108  static string module("");
109  if ( module == "" ) {
110  if (processHandle() and moduleHandle()) {
111  char name[PATH_MAX] = {"Unknown.module"};
112  name[0] = 0;
113  const char *path =
114  (reinterpret_cast<Dl_info*>(moduleHandle())->dli_fname);
115  if (::realpath(path, name)) {
116  module = name;
117  }
118  }
119  }
120  return module;
121 }
122 
125  static ModuleType type = ModuleType::UNKNOWN;
126  if (type == ModuleType::UNKNOWN) {
127  const string& module = moduleNameFull();
128  std::size_t loc = module.rfind('.')+1;
129  if (loc == 0) {
130  type = ModuleType::EXECUTABLE;
131  } else if (module[loc] == 'e' or module[loc] == 'E') {
132  type = ModuleType::EXECUTABLE;
133  } else if (module[loc] == 's' and module[loc+1] == 'o') {
134  type = ModuleType::SHAREDLIB;
135  } else {
136  type = ModuleType::UNKNOWN;
137  }
138  }
139  return type;
140 }
141 
143 void* processHandle() {
144  static std::int64_t pid = ::getpid();
145  static void* hP = reinterpret_cast<void*>(pid);
146  return hP;
147 }
148 
150  s_module_handle = handle;
151 }
152 
154  if (0 == s_module_handle) {
155  if (processHandle()) {
156  static Dl_info info;
157  if (0 != ::dladdr(FuncPtrCast<void*>(moduleHandle), &info)) {
158  return &info;
159  }
160  }
161  }
162  return s_module_handle;
163 }
164 
166  // This does NOT work!
167  static Dl_info infoBuf;
168  static Dl_info *info;
169 
170  if (0 == info) {
171  void* handle = ::dlopen(0, RTLD_LAZY);
172  if (0 != handle) {
173  void* func = ::dlsym(handle, "main");
174  if (0 != func) {
175  if (0 != ::dladdr(func, &infoBuf)) {
176  info = &infoBuf;
177  }
178  }
179  }
180  }
181  return info;
182 }
183 
184 
185 const string& exeName() {
186  static string module("");
187  if (module.length() == 0) {
188  module = getExecutablePath().string();
189  }
190  return module;
191 }
192 
194 
195  Path::Item self_proc {"/proc/self"};
196 
197  Path::Item exe = self_proc / "exe";
198 
199  if (not boost::filesystem::exists(exe)) {
200  std::stringstream self_str {};
201  self_str << "/proc/" << ::getpid();
202  self_proc = Path::Item(self_str.str());
203  }
204 
205  return self_proc;
206 
207 }
208 
210 
211  vector<Path::Item> linked_modules;
212 
213  Path::Item self_maps = getSelfProc() / "maps";
214  std::ifstream maps_str(self_maps.string());
215 
216  string line;
217  while (std::getline(maps_str, line)) {
218  string address, perms, offset, dev, pathname;
219  unsigned inode;
220  std::istringstream iss(line);
221  if (not(iss >> address >> perms >> offset >> dev >> inode >> pathname)) {
222  continue;
223  }
224  if (perms == "r-xp" and boost::filesystem::exists(pathname)) {
225  linked_modules.emplace_back(Path::Item(pathname));
226  }
227  }
228 
229  maps_str.close();
230 
231  return linked_modules;
232 
233 }
234 
236 
237  if (s_linkedModules.size() == 0) {
238 
239  for (auto m : linkedModulePaths()) {
240  s_linkedModules.emplace_back(m.string());
241  }
242 
243  }
244  return s_linkedModules;
245 }
246 
248 
249 #ifdef __APPLE__
250  path self_proc {};
251  char pathbuf[PATH_MAX + 1];
252  unsigned int bufsize = sizeof(pathbuf);
253  _NSGetExecutablePath(pathbuf, &bufsize);
254  path self_exe = path(string(pathbuf));
255 #else
256 
257  Path::Item self_exe = getSelfProc() / "exe";
258 
259 #endif
260 
261  return boost::filesystem::canonical(self_exe);
262 }
263 
264 } // namespace System
265 } // namespace Elements
defines a Small helper function that allows the cast from void * to function pointer
OS specific details to access at run-time the module configuration of the process.
provide functions to retrieve resources pointed by environment variables
const void * addresse() const
Definition: ModuleInfo.cpp:79
std::unique_ptr< Dl_info > m_dlinfo
Definition: ModuleInfo.h:54
const std::string name() const
Definition: ModuleInfo.cpp:71
const std::string libraryName() const
Definition: ModuleInfo.cpp:75
T close(T... args)
T emplace_back(T... args)
T find(T... args)
T get(T... args)
T getline(T... args)
Elements::Path::Item path
Definition: DataSyncUtils.h:39
boost::filesystem::path Item
Definition: Path.h:61
void * ImageHandle
Definition of an image handle.
Definition: System.h:118
ELEMENTS_API void setModuleHandle(ImageHandle handle)
Attach module handle.
Definition: ModuleInfo.cpp:149
ELEMENTS_API Path::Item getSelfProc()
Get the path to the /proc directory of the process.
Definition: ModuleInfo.cpp:193
ELEMENTS_API ProcessHandle processHandle()
Handle to running process.
Definition: ModuleInfo.cpp:143
ELEMENTS_API ImageHandle moduleHandle()
Handle to currently executed module.
Definition: ModuleInfo.cpp:153
ELEMENTS_API ImageHandle exeHandle()
Handle to the executable file running.
Definition: ModuleInfo.cpp:165
ELEMENTS_API const std::string & moduleNameFull()
Get the full name of the (executable/DLL) file.
Definition: ModuleInfo.cpp:107
ELEMENTS_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:95
ELEMENTS_API Path::Item getExecutablePath()
Get the full executable path.
Definition: ModuleInfo.cpp:247
ELEMENTS_API ModuleType moduleType()
Get type of the module.
Definition: ModuleInfo.cpp:124
ELEMENTS_API const std::vector< std::string > linkedModules()
Vector of names of linked modules.
Definition: ModuleInfo.cpp:235
ELEMENTS_API std::vector< Path::Item > linkedModulePaths()
Definition: ModuleInfo.cpp:209
ELEMENTS_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:185
constexpr double m
Definition: SystemOfUnits.h:79
T reset(T... args)
T rfind(T... args)
T length(T... args)
T substr(T... args)