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