diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7d95f0693d4d..c26a7eb6d092 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1041,6 +1041,7 @@ std::string EvalState::mkSingleDerivedPathStringRaw(const SingleDerivedPath & p) auto optStaticOutputPath = std::visit( overloaded{ [&](const SingleDerivedPath::Opaque & o) { + store->addTempRoot(o.path); waitForPath(o.path); auto drv = store->readDerivation(o.path); auto i = drv.outputs.find(b.output); diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 03a1aa455ce0..8ae89fd2d565 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -25,6 +25,9 @@ PackageInfo::PackageInfo(EvalState & state, ref store, const std::string this->drvPath = drvPath; + /* Prevent GC from deleting the .drv between now and when the + build phase adds its own temp root. */ + store->addTempRoot(drvPath); auto drv = store->derivationFromPath(drvPath); name = drvPath.name(); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index a997c96c760f..c7e5b143b2e4 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -309,6 +309,10 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v if (!state.store->isStorePath(path2)) return std::nullopt; auto storePath = state.store->parseStorePath(path2); + /* Add a temp root before checking validity or reading the + derivation, to prevent GC from deleting the path between + our validity check and the subsequent readDerivation(). */ + state.store->addTempRoot(storePath); state.waitForPath(storePath); if (!(state.store->isValidPath(storePath) && isDerivation(path2))) return std::nullopt; @@ -1760,9 +1764,14 @@ static void derivationStrictInternal( /* !!! This doesn't work if readOnlyMode is set. */ StorePathSet refs; // FIXME: don't need to wait, we only need the references. + state.store->addTempRoot(d.drvPath); state.waitForPath(d.drvPath); state.store->computeFSClosure(d.drvPath, refs); for (auto & j : refs) { + /* Prevent GC from deleting derivations in the + closure before we can read them. */ + if (j.isDerivation()) + state.store->addTempRoot(j); drv.inputSrcs.insert(j); if (j.isDerivation()) { drv.inputDrvs.map[j].value = state.store->readDerivation(j).outputNames();