Skip to content

Commit

Permalink
Fix #11141 broken sp corrector
Browse files Browse the repository at this point in the history
  • Loading branch information
roberth committed Jul 22, 2024
1 parent 0ec5e3a commit 380becf
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/libexpr/eval-gc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
// NOTE: We assume the stack grows down, as it does on all architectures we support.
// Architectures that grow the stack up are rare.
if (sp >= osStackBase || sp < osStackLow) { // lo is outside the os stack
sp = osStackBase;
sp = osStackLow;
}
}

Expand Down
34 changes: 34 additions & 0 deletions tests/functional/lang-gc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# shellcheck shell=bash

# Regression tests for the evaluator
# These are not in lang.sh because they generally only need to run in CI,
# whereas lang.sh is often run locally during development


source common.sh

set -o pipefail

# Regression test for #11141. The stack pointer corrector assigned the base
# instead of the top (which resides at the low end of the stack). Sounds confusing?
# Stacks grow downwards, so that's why this mistake happened.
# My manual testing did not uncover this, because it didn't rely on the stack enough.
# https://github.com/NixOS/nix/issues/11141
test_issue_11141() {
mkdir -p "$TEST_ROOT/issue-11141/src"
cp lang-gc/issue-11141-gc-coroutine-test.nix "$TEST_ROOT/issue-11141/"
(
set +x;
n=10
echo "populating $TEST_ROOT/issue-11141/src with $((n*100)) files..."
for i in $(seq 0 $n); do
touch "$TEST_ROOT/issue-11141/src/file-$i"{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
done
)

GC_INITIAL_HEAP_SIZE=$((1024 * 1024)) \
NIX_SHOW_STATS=1 \
nix eval -vvv\
-f "$TEST_ROOT/issue-11141/issue-11141-gc-coroutine-test.nix"
}
test_issue_11141
65 changes: 65 additions & 0 deletions tests/functional/lang-gc/issue-11141-gc-coroutine-test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

# Run:
# GC_INITIAL_HEAP_SIZE=$[1024 * 1024] NIX_SHOW_STATS=1 nix eval -f gc-coroutine-test.nix -vvvv

let
inherit (builtins)
foldl'
isList
;

# Generate a tree of numbers, n deep, such that the numbers add up to (1 + salt) * 10^n.
# The salting makes the numbers all different, increasing the likelihood of catching
# any memory corruptions that might be caused by the GC or otherwise.
garbage = salt: n:
if n == 0
then [(1 + salt)]
else [
(garbage (10 * salt + 1) (n - 1))
(garbage (10 * salt - 1) (n - 1))
(garbage (10 * salt + 2) (n - 1))
(garbage (10 * salt - 2) (n - 1))
(garbage (10 * salt + 3) (n - 1))
(garbage (10 * salt - 3) (n - 1))
(garbage (10 * salt + 4) (n - 1))
(garbage (10 * salt - 4) (n - 1))
(garbage (10 * salt + 5) (n - 1))
(garbage (10 * salt - 5) (n - 1))
];

pow = base: n:
if n == 0
then 1
else base * (pow base (n - 1));

sumNestedLists = l:
if isList l
then foldl' (a: b: a + sumNestedLists b) 0 l
else l;

in
assert sumNestedLists (garbage 0 3) == pow 10 3;
assert sumNestedLists (garbage 0 6) == pow 10 6;
builtins.foldl'
(a: b:
assert
"${
builtins.path {
path = ./src;
filter = path: type:
# We're not doing common subexpression elimination, so this reallocates
# the fairly big tree over and over, producing a lot of garbage during
# source filtering, whose filter runs in a coroutine.
assert sumNestedLists (garbage 0 3) == pow 10 3;
true;
}
}"
== "${./src}";

# These asserts don't seem necessary, as the lambda value get corrupted first
assert a.okay;
assert b.okay;
{ okay = true; }
)
{ okay = true; }
[ { okay = true; } { okay = true; } { okay = true; } ]
1 change: 1 addition & 0 deletions tests/functional/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ nix_tests = \
remote-store.sh \
legacy-ssh-store.sh \
lang.sh \
lang-gc.sh \
characterisation-test-infra.sh \
experimental-features.sh \
fetchMercurial.sh \
Expand Down

0 comments on commit 380becf

Please sign in to comment.