1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-24 22:11:15 +02:00

Merge pull request #13142 from xokdvium/gc-root-boost-regex

libstore: Use `boost::regex` for GC root discovery
This commit is contained in:
Jörg Thalheim 2025-05-18 21:44:41 +02:00 committed by GitHub
commit e7078d4de1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 15 deletions

View file

@ -63,6 +63,7 @@ scope: {
"--with-coroutine" "--with-coroutine"
"--with-iostreams" "--with-iostreams"
]; ];
enableIcu = false;
}).overrideAttrs }).overrideAttrs
(old: { (old: {
# Need to remove `--with-*` to use `--with-libraries=...` # Need to remove `--with-*` to use `--with-libraries=...`

View file

@ -13,10 +13,11 @@
# include "nix/util/processes.hh" # include "nix/util/processes.hh"
#endif #endif
#include <boost/regex.hpp>
#include <functional> #include <functional>
#include <queue> #include <queue>
#include <algorithm> #include <algorithm>
#include <regex>
#include <random> #include <random>
#include <climits> #include <climits>
@ -331,8 +332,8 @@ static void readProcLink(const std::filesystem::path & file, UncheckedRoots & ro
static std::string quoteRegexChars(const std::string & raw) static std::string quoteRegexChars(const std::string & raw)
{ {
static auto specialRegex = std::regex(R"([.^$\\*+?()\[\]{}|])"); static auto specialRegex = boost::regex(R"([.^$\\*+?()\[\]{}|])");
return std::regex_replace(raw, specialRegex, R"(\$&)"); return boost::regex_replace(raw, specialRegex, R"(\$&)");
} }
#ifdef __linux__ #ifdef __linux__
@ -354,12 +355,12 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
auto procDir = AutoCloseDir{opendir("/proc")}; auto procDir = AutoCloseDir{opendir("/proc")};
if (procDir) { if (procDir) {
struct dirent * ent; struct dirent * ent;
auto digitsRegex = std::regex(R"(^\d+$)"); static const auto digitsRegex = boost::regex(R"(^\d+$)");
auto mapRegex = std::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)"); static const auto mapRegex = boost::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)");
auto storePathRegex = std::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)"); auto storePathRegex = boost::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)");
while (errno = 0, ent = readdir(procDir.get())) { while (errno = 0, ent = readdir(procDir.get())) {
checkInterrupt(); checkInterrupt();
if (std::regex_match(ent->d_name, digitsRegex)) { if (boost::regex_match(ent->d_name, digitsRegex)) {
try { try {
readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked); readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked); readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
@ -386,15 +387,15 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
std::filesystem::path mapFile = fmt("/proc/%s/maps", ent->d_name); std::filesystem::path mapFile = fmt("/proc/%s/maps", ent->d_name);
auto mapLines = tokenizeString<std::vector<std::string>>(readFile(mapFile.string()), "\n"); auto mapLines = tokenizeString<std::vector<std::string>>(readFile(mapFile.string()), "\n");
for (const auto & line : mapLines) { for (const auto & line : mapLines) {
auto match = std::smatch{}; auto match = boost::smatch{};
if (std::regex_match(line, match, mapRegex)) if (boost::regex_match(line, match, mapRegex))
unchecked[match[1]].emplace(mapFile.string()); unchecked[match[1]].emplace(mapFile.string());
} }
auto envFile = fmt("/proc/%s/environ", ent->d_name); auto envFile = fmt("/proc/%s/environ", ent->d_name);
auto envString = readFile(envFile); auto envString = readFile(envFile);
auto env_end = std::sregex_iterator{}; auto env_end = boost::sregex_iterator{};
for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i) for (auto i = boost::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i)
unchecked[i->str()].emplace(envFile); unchecked[i->str()].emplace(envFile);
} catch (SystemError & e) { } catch (SystemError & e) {
if (errno == ENOENT || errno == EACCES || errno == ESRCH) if (errno == ENOENT || errno == EACCES || errno == ESRCH)
@ -413,12 +414,12 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
// Because of this we disable lsof when running the tests. // Because of this we disable lsof when running the tests.
if (getEnv("_NIX_TEST_NO_LSOF") != "1") { if (getEnv("_NIX_TEST_NO_LSOF") != "1") {
try { try {
std::regex lsofRegex(R"(^n(/.*)$)"); boost::regex lsofRegex(R"(^n(/.*)$)");
auto lsofLines = auto lsofLines =
tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n"); tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n");
for (const auto & line : lsofLines) { for (const auto & line : lsofLines) {
std::smatch match; boost::smatch match;
if (std::regex_match(line, match, lsofRegex)) if (boost::regex_match(line, match, lsofRegex))
unchecked[match[1].str()].emplace("{lsof}"); unchecked[match[1].str()].emplace("{lsof}");
} }
} catch (ExecError & e) { } catch (ExecError & e) {

View file

@ -94,7 +94,7 @@ subdir('nix-meson-build-support/libatomic')
boost = dependency( boost = dependency(
'boost', 'boost',
modules : ['container'], modules : ['container', 'regex'],
include_type: 'system', include_type: 'system',
) )
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we # boost is a public dependency, but not a pkg-config dependency unfortunately, so we