#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{file}, std::istreambuf_iterator{}}; if (!contents.starts_with(name)) { continue; } const std::string pathname = pid.path(); const auto pos = static_cast(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