Elements 6.1.2
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 <dlfcn.h>
25#include <libgen.h>
26#include <sys/param.h>
27#include <sys/times.h>
28#include <unistd.h>
29
30#ifdef __APPLE__
31#include <mach-o/dyld.h> // for _NSGetExecutablePath
32#endif
33
34#include <array>
35#include <cerrno>
36#include <cstdint>
37#include <cstdio>
38#include <cstdlib>
39#include <cstring>
40#include <fstream> // for ifstream
41#include <iostream>
42#include <sstream> // for stringstream
43#include <string> // for string
44#include <vector>
45
46#ifdef __APPLE__
47#include <climits> // for PATH_MAX
48#endif
49
50#include <boost/filesystem/operations.hpp> // for filesystem::exists, canonical
51
53#include "ElementsKernel/Path.h" // for Path::Item
54
55using std::string;
56using std::vector;
57
58namespace {
59vector<string> s_linkedModules;
60}
61
62namespace Elements {
63namespace System {
64
65ModuleInfo::ModuleInfo() : m_dlinfo{nullptr} {}
66
68 m_dlinfo.reset(new Dl_info);
69 ::dladdr(FuncPtrCast<void*>(funct), m_dlinfo.get());
70}
71
72const string ModuleInfo::name() const {
73 return ::basename(const_cast<char*>(m_dlinfo->dli_fname));
74}
75
76const string ModuleInfo::libraryName() const {
77 return const_cast<char*>(m_dlinfo->dli_fname);
78}
79
80const void* ModuleInfo::addresse() const {
81 return m_dlinfo->dli_saddr;
82}
83
84bool ModuleInfo::isEmpty() const {
85 return (m_dlinfo == nullptr);
86}
87
88ModuleInfo::operator const Dl_info&() const {
89 return *m_dlinfo;
90}
91
92namespace {
93ImageHandle s_module_handle = nullptr;
94}
96const string& moduleName() {
97 static string module{};
98 if (module.empty()) {
99 if ((processHandle() != nullptr) and (moduleHandle() != nullptr)) {
100 string mod = ::basename(const_cast<char*>((reinterpret_cast<Dl_info*>(moduleHandle()))->dli_fname));
101 module = mod.substr(static_cast<string::size_type>(0), mod.find('.'));
102 }
103 }
104 return module;
105}
106
108const string& moduleNameFull() {
109 static string module{};
110 if (module.empty()) {
111 if (processHandle() and moduleHandle()) {
112 std::array<char, PATH_MAX> name{"Unknown.module"};
113 name[0] = 0;
114 const char* path = (reinterpret_cast<Dl_info*>(moduleHandle())->dli_fname);
115 if (::realpath(path, name.data())) {
116 module = name.data();
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) {
131 } else if (module[loc] == 'e' or module[loc] == 'E') {
133 } else if (module[loc] == 's' and module[loc + 1] == 'o') {
135 } else {
136 type = ModuleType::UNKNOWN;
137 }
138 }
139 return type;
140}
141
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 (nullptr == s_module_handle) {
155 if (processHandle() != nullptr) {
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 (nullptr == info) {
171 void* handle = ::dlopen(nullptr, RTLD_LAZY);
172 if (nullptr != handle) {
173 void* func = ::dlsym(handle, "main");
174 if (nullptr != func) {
175 if (0 != ::dladdr(func, &infoBuf)) {
176 info = &infoBuf;
177 }
178 }
179 }
180 }
181 return info;
182}
183
184const string& exeName() {
185 static string module{""};
186 if (module.empty()) {
187 module = getExecutablePath().string();
188 }
189 return module;
190}
191
192Path::Item getSelfProc() {
193
194 Path::Item self_proc{"/proc/self"};
195
196 Path::Item exe = self_proc / "exe";
197
198 if (not boost::filesystem::exists(exe)) {
199 std::stringstream self_str{};
200 self_str << "/proc/" << ::getpid();
201 self_proc = Path::Item(self_str.str());
202 }
203
204 return self_proc;
205}
206
208
209 vector<Path::Item> linked_modules;
210
211 Path::Item self_maps = getSelfProc() / "maps";
212 std::ifstream maps_str(self_maps.string());
213
214 string line;
215 while (std::getline(maps_str, line)) {
216 string address;
217 string perms;
218 string offset;
219 string dev;
220 string pathname;
221 unsigned inode;
222 std::istringstream iss(line);
223 if (not(iss >> address >> perms >> offset >> dev >> inode >> pathname)) {
224 continue;
225 }
226 if (perms == "r-xp" and boost::filesystem::exists(pathname)) {
227 linked_modules.emplace_back(Path::Item(pathname));
228 }
229 }
230
231 maps_str.close();
232
233 return linked_modules;
234}
235
237
238 if (s_linkedModules.size() == 0) {
239
240 for (auto m : linkedModulePaths()) {
241 s_linkedModules.emplace_back(m.string());
242 }
243 }
244 return s_linkedModules;
245}
246
247Path::Item getExecutablePath() {
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
OS specific details to access at run-time the module configuration of the process.
defines a Small helper function that allows the cast from void * to function pointer
provide functions to retrieve resources pointed by environment variables
const void * addresse() const
Definition: ModuleInfo.cpp:80
std::unique_ptr< Dl_info > m_dlinfo
Definition: ModuleInfo.h:55
const std::string name() const
Definition: ModuleInfo.cpp:72
const std::string libraryName() const
Definition: ModuleInfo.cpp:76
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:149
ELEMENTS_API Path::Item getSelfProc()
Get the path to the /proc directory of the process.
Definition: ModuleInfo.cpp:192
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:108
ELEMENTS_API const std::string & moduleName()
Get the name of the (executable/DLL) file without file-type.
Definition: ModuleInfo.cpp:96
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:236
ELEMENTS_API std::vector< Path::Item > linkedModulePaths()
Definition: ModuleInfo.cpp:207
ELEMENTS_API const std::string & exeName()
Name of the executable file running.
Definition: ModuleInfo.cpp:184
T reset(T... args)
T rfind(T... args)
T substr(T... args)