-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GitLab CI: hack to deal with GHC heisenbug
Every now and then, GHC will exit with the error ``` out: mmap 131072 bytes at (nil): Cannot allocate memory out: Try specifying an address with +RTS -xm<addr> -RTS out: internal error: m32_allocator_init: Failed to map (GHC version 9.0.2 for x86_64_unknown_linux) Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug ``` (when the binary is named `out`). For some reason this problem has become more pronounced for us. Since we invoke GHC/Clash an awful amount of times in some of our CI tests, the chances of hitting it in one of those invocations are really high. Additionally, it seems some binaries have really high odds of exhibiting the issue. This commit wraps the `ghc`, `ghci`, `clash` and `clashi` binaries in a Bash script that will retry for a total of twenty(!) times when this error message is observed. The number of retries can be configured with the "-t" option argument. However, the test suite also compiles Haskell code to a binary and then runs that binary. These binaries have the same issues, but they don't come from the PATH, so we can't intercept them like we can for things that are on the PATH. For this, we introduce a new Tasty test provider that also tries up to twenty times when the heisenbug's error message is observed. We need both solutions because we are also seeing the problem on `doctests` wich don't involve our Tasty test providers, so these need to be covered by the script approach. Any `clash` invocations from Tasty are not retried since the Bash script already does that. We think this problem occurs on every combination of GHC version and Linux kernel version, but we are seeing it (almost?) exclusively on GHC 9.0.2.
- Loading branch information
1 parent
4791875
commit 5389ecc
Showing
10 changed files
with
213 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../wrap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../wrap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../wrap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../wrap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/bin/bash | ||
|
||
# Every now and then, GHC will exit with the error | ||
# | ||
# out: mmap 131072 bytes at (nil): Cannot allocate memory | ||
# out: Try specifying an address with +RTS -xm<addr> -RTS | ||
# out: internal error: m32_allocator_init: Failed to map | ||
# (GHC version 9.0.2 for x86_64_unknown_linux) | ||
# Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug | ||
# | ||
# (when the binary is named `out`). | ||
# | ||
# Since we invoke GHC/Clash an awful amount of times in some of our CI tests, | ||
# the chances of hitting it in one of those invocations are really high. | ||
# Additionally, it seems some binaries have really high odds of exhibiting the | ||
# issue. | ||
# | ||
# This script wraps the relevant binaries and will retry for a total of | ||
# twenty(!) times when this error message is observed. The number of retries | ||
# can be configured with the "-t" option argument. | ||
# | ||
# The mmap error message itself will not be observed on stdout and stderr of | ||
# this script, but anything printed before that by the wrapped binary will | ||
# occur multiple times as the binary is run again. Given that we usually test | ||
# either that stdout or stderr is empty or that it contains or does not | ||
# contain a certain string, duplication does not affect the outcome of the | ||
# test. | ||
# | ||
# We think this problem occurs on every combination of GHC version and | ||
# Linux kernel version, but we are seeing it (almost?) exclusively on GHC | ||
# 9.0.2. | ||
|
||
unset VERBOSE MAXTRIES PROG TRIES STATUS | ||
|
||
MAXTRIES=20 | ||
while true; do | ||
case "$1" in | ||
-v) | ||
VERBOSE=1 | ||
;; | ||
-t) | ||
MAXTRIES="$2" | ||
shift | ||
;; | ||
*) | ||
break | ||
;; | ||
esac | ||
shift | ||
done | ||
|
||
PROG="$1" | ||
shift | ||
|
||
exec 3>&1 | ||
|
||
TRIES=1 | ||
[[ -n $VERBOSE ]] && echo "retry-ghc-heisenbug: Run $PROG" >&2 | ||
while true; do | ||
"$PROG" "$@" 2>&1 >&3 | \ | ||
awk ' | ||
/mmap 131072 bytes at \(nil\): Cannot allocate memory/ \ | ||
{ exit 1 } | ||
{ print }' >&2 | ||
STATUS=("${PIPESTATUS[@]}") | ||
[[ ${STATUS[1]} -eq 0 ]] && exit ${STATUS[0]} | ||
((TRIES++)) | ||
[[ $TRIES -gt $MAXTRIES ]] && break | ||
[[ -n $VERBOSE ]] && echo "retry-ghc-heisenbug: RETRYING due to heisenbug (try: $TRIES)" >&2 | ||
done | ||
|
||
exec 3>&- | ||
|
||
echo "retry-ghc-heisenbug: Heisenbug limit EXCEEDED" >&2 | ||
exit -6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash | ||
|
||
unset PROG PROGDIR REALPROG | ||
|
||
PROG="$(basename $0)" | ||
PROGDIR="$(dirname $0)" | ||
|
||
if [[ -n "$RETRY_GHC_HEISENBUG_LOOP_DETECT" ]]; then | ||
echo "retry-ghc-heisenbug: Loop detected, aborting" >&2 | ||
exit 1 | ||
fi | ||
export RETRY_GHC_HEISENBUG_LOOP_DETECT=1 | ||
|
||
REALPROG="$(which -a $PROG | tail -n+2 | head -n1)" | ||
|
||
if [[ -z "$REALPROG" ]]; then | ||
echo "retry-ghc-heisenbug: Real $PROG not found, aborting" >&2 | ||
exit 1 | ||
fi | ||
|
||
"$PROGDIR/../script" "$REALPROG" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters