From f34b52b52163ec0db60dca6907f309acc45e2205 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 1 May 2024 18:47:19 +0200 Subject: [PATCH] libexpr: Add missing GC root for baseEnv This missing GC root wasn't much of a problem before, because the heap would end up with a reference to the `baseEnv` pretty soon, but when unit testing, the construction of `EvalState` doesn't necessarily happen well before GC runs for the first time. Found while unit testing the Rust bindings that currently reside at https://github.com/nixops4/nixops4/tree/main/rust --- src/libexpr/eval.cc | 8 +++++++- src/libexpr/eval.hh | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 35ccca79a..aa058b04f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -342,6 +343,8 @@ void initGC() gcInitialised = true; } +static constexpr size_t BASE_ENV_SIZE = 128; + EvalState::EvalState( const LookupPath & _lookupPath, ref store, @@ -424,8 +427,11 @@ EvalState::EvalState( #if HAVE_BOEHMGC , valueAllocCache(std::allocate_shared(traceable_allocator(), nullptr)) , env1AllocCache(std::allocate_shared(traceable_allocator(), nullptr)) + , baseEnvP(std::allocate_shared(traceable_allocator(), &allocEnv(BASE_ENV_SIZE))) + , baseEnv(**baseEnvP) +#else + , baseEnv(allocEnv(BASE_ENV_SIZE)) #endif - , baseEnv(allocEnv(128)) , staticBaseEnv{std::make_shared(nullptr, nullptr)} { corepkgsFS->setPathDisplay(""); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 508361301..ae8b9dd04 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -547,6 +547,11 @@ public: */ SingleDerivedPath coerceToSingleDerivedPath(const PosIdx pos, Value & v, std::string_view errorCtx); +#if HAVE_BOEHMGC + /** A GC root for the baseEnv reference. */ + std::shared_ptr baseEnvP; +#endif + public: /**