aboutsummaryrefslogtreecommitdiff
path: root/src/memory/maps.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/maps.cc')
-rw-r--r--src/memory/maps.cc60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/memory/maps.cc b/src/memory/maps.cc
new file mode 100644
index 0000000..290675a
--- /dev/null
+++ b/src/memory/maps.cc
@@ -0,0 +1,60 @@
+#include "memory/maps.hh"
+
+namespace memory {
+
+static std::string get_pid_from_name(const std::string& name) {
+ for (const auto& pid : std::filesystem::directory_iterator("/proc")) {
+ if (!pid.is_directory()) {
+ continue;
+ }
+
+ std::ifstream file{std::string{pid.path()} + "/comm"};
+ if (!file.is_open()) {
+ continue;
+ }
+ const std::string contents{std::istreambuf_iterator<char>{file},
+ std::istreambuf_iterator<char>{}};
+ if (!contents.starts_with(name)) {
+ continue;
+ }
+
+ const std::string pathname = pid.path();
+ const auto pos = static_cast<long>(pathname.find_last_of('/'));
+ return {std::next(std::begin(pathname) + pos), std::end(pathname)};
+ }
+
+ throw std::runtime_error{"failed to get pid from name \"" + name +
+ "\", is it open?"};
+}
+
+maps::maps(const char* const name) : pid(get_pid_from_name(name)) {
+ std::ifstream file{"/proc/" + this->pid + "/maps"};
+ if (!file.is_open()) {
+ throw std::runtime_error{"failed to open maps for pid \"" + this->pid +
+ '\"'};
+ }
+ std::stringstream file_ss;
+ file_ss << file.rdbuf();
+ for (std::string line; std::getline(file_ss, line);) {
+ if (line.empty()) {
+ continue;
+ }
+
+ std::stringstream line_ss{line};
+
+ // address perms offset dev inode pathname
+ // 00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
+ maps::region region;
+ line_ss >> region.start;
+ line_ss.ignore(); // ignore dash
+ line_ss >> region.end;
+ line_ss >> region.perms;
+ line_ss >> region.offset;
+ line_ss >> region.dev;
+ line_ss >> region.inode;
+ line_ss >> region.pathname;
+ this->regions.push_back(std::move(region));
+ }
+}
+
+} // namespace memory