File: test.bash

package info (click to toggle)
golang-1.7 1.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 67,884 kB
  • ctags: 135,139
  • sloc: asm: 43,658; ansic: 7,818; sh: 1,492; perl: 1,131; xml: 623; python: 286; yacc: 155; makefile: 109; cpp: 22; f90: 8; awk: 7
file content (162 lines) | stat: -rwxr-xr-x 4,566 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env bash
# Copyright 2015 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This directory is intended to test the use of Go with sanitizers
# like msan, asan, etc.  See https://github.com/google/sanitizers .

set -e

# The sanitizers were originally developed with clang, so prefer it.
CC=cc
if test -x "$(type -p clang)"; then
  CC=clang
fi
export CC

msan=yes

TMPDIR=${TMPDIR:-/tmp}
echo 'int main() { return 0; }' > ${TMPDIR}/testsanitizers$$.c
if $CC -fsanitize=memory -c ${TMPDIR}/testsanitizers$$.c -o ${TMPDIR}/testsanitizers$$.o 2>&1 | grep "unrecognized" >& /dev/null; then
  echo "skipping msan tests: -fsanitize=memory not supported"
  msan=no
fi
rm -f ${TMPDIR}/testsanitizers$$.*

tsan=yes

# The memory and thread sanitizers in versions of clang before 3.6
# don't work with Go.
if test "$msan" = "yes" && $CC --version | grep clang >& /dev/null; then
  ver=$($CC --version | sed -e 's/.* version \([0-9.-]*\).*/\1/')
  major=$(echo $ver | sed -e 's/\([0-9]*\).*/\1/')
  minor=$(echo $ver | sed -e 's/[0-9]*\.\([0-9]*\).*/\1/')
  if test "$major" -lt 3 || test "$major" -eq 3 -a "$minor" -lt 6; then
    echo "skipping msan/tsan tests: clang version $major.$minor (older than 3.6)"
    msan=no
    tsan=no
  fi

  # Clang before 3.8 does not work with Linux at or after 4.1.
  # golang.org/issue/12898.
  if test "$msan" = "yes" -a "$major" -lt 3 || test "$major" -eq 3 -a "$minor" -lt 8; then
    if test "$(uname)" = Linux; then
      linuxver=$(uname -r)
      linuxmajor=$(echo $linuxver | sed -e 's/\([0-9]*\).*/\1/')
      linuxminor=$(echo $linuxver | sed -e 's/[0-9]*\.\([0-9]*\).*/\1/')
      if test "$linuxmajor" -gt 4 || test "$linuxmajor" -eq 4 -a "$linuxminor" -ge 1; then
        echo "skipping msan/tsan tests: clang version $major.$minor (older than 3.8) incompatible with linux version $linuxmajor.$linuxminor (4.1 or newer)"
	msan=no
	tsan=no
      fi
    fi
  fi
fi

status=0

if test "$msan" = "yes"; then
    if ! go build -msan std; then
	echo "FAIL: build -msan std"
	status=1
    fi

    if ! go run -msan msan.go; then
	echo "FAIL: msan"
	status=1
    fi

    if ! CGO_LDFLAGS="-fsanitize=memory" CGO_CPPFLAGS="-fsanitize=memory" go run -msan -a msan2.go; then
	echo "FAIL: msan2 with -fsanitize=memory"
	status=1
    fi

    if ! go run -msan -a msan2.go; then
	echo "FAIL: msan2"
	status=1
    fi

    if ! go run -msan msan3.go; then
	echo "FAIL: msan3"
	status=1
    fi

    if ! go run -msan msan4.go; then
	echo "FAIL: msan4"
	status=1
    fi

    if go run -msan msan_fail.go 2>/dev/null; then
	echo "FAIL: msan_fail"
	status=1
    fi
fi

if test "$tsan" = "yes"; then
    echo 'int main() { return 0; }' > ${TMPDIR}/testsanitizers$$.c
    ok=yes
    if ! $CC -fsanitize=thread ${TMPDIR}/testsanitizers$$.c -o ${TMPDIR}/testsanitizers$$ &> ${TMPDIR}/testsanitizers$$.err; then
	ok=no
    fi
     if grep "unrecognized" ${TMPDIR}/testsanitizers$$.err >& /dev/null; then
	echo "skipping tsan tests: -fsanitize=thread not supported"
	tsan=no
     elif test "$ok" != "yes"; then
	 cat ${TMPDIR}/testsanitizers$$.err
	 echo "skipping tsan tests: -fsanitizer=thread build failed"
	 tsan=no
     fi
     rm -f ${TMPDIR}/testsanitizers$$*
fi

# Run a TSAN test.
# $1 test name
# $2 environment variables
# $3 go run args
testtsan() {
    err=${TMPDIR}/tsanerr$$.out
    if ! env $2 go run $3 $1 2>$err; then
	cat $err
	echo "FAIL: $1"
	status=1
    elif grep -i warning $err >/dev/null 2>&1; then
	cat $err
	echo "FAIL: $1"
	status=1
    fi
    rm -f $err
}

if test "$tsan" = "yes"; then
    testtsan tsan.go
    testtsan tsan2.go
    testtsan tsan3.go
    testtsan tsan4.go

    # These tests are only reliable using clang or GCC version 7 or later.
    # Otherwise runtime/cgo/libcgo.h can't tell whether TSAN is in use.
    ok=false
    if ${CC} --version | grep clang >/dev/null 2>&1; then
	ok=true
    else
	ver=$($CC -dumpversion)
	major=$(echo $ver | sed -e 's/\([0-9]*\).*/\1/')
	if test "$major" -lt 7; then
	    echo "skipping remaining TSAN tests: GCC version $major (older than 7)"
	else
	    ok=true
	fi
    fi

    if test "$ok" = "true"; then
	# This test requires rebuilding os/user with -fsanitize=thread.
	testtsan tsan5.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"

	# This test requires rebuilding runtime/cgo with -fsanitize=thread.
	testtsan tsan6.go "CGO_CFLAGS=-fsanitize=thread CGO_LDFLAGS=-fsanitize=thread" "-installsuffix=tsan"
    fi
fi

exit $status