golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.43k stars 17.71k forks source link

runtime: go test -race on FreeBSD with ASLR reports ok without running any test #65425

Open xiaq opened 10 months ago

xiaq commented 10 months ago

Go version

go version go1.21.6 freebsd/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/.cache/go-build'
GOENV='/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='freebsd'
GOINSECURE=''
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='freebsd'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/freebsd_amd64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/tmp/cirrus-ci-build/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2387445335=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Ensure ASLR is enabled:

sysctl kern.elf64.aslr.enable=1

Write a test that fails. For reasons I don't understand, this issue only reproduces when the test imports plugin.

// a_test.go
package main_test

import (
        "testing"
        _ "plugin"
)

func TestFail(t *testing.T) {
        t.FailNow()
}

Run the test without -race and it fails, as expected:

# go test
--- FAIL: TestFail (0.00s)
FAIL
exit status 1
FAIL    src.elv.sh/d    0.003s

However, if you run the test with -race, it prints out a warning message and goes on to report the test as if it succeeded:

# go test -race; echo $?
This sanitizer is not compatible with enabled ASLR and binaries compiled with PIE
ok      src.elv.sh/d    0.006s
0

Since the test always fails, it seems that go test -race doesn't actually run the test.

What did you see happen?

go test -race reports "ok" and exits with 0.

What did you expect to see?

go test -race should report failure and exit with 1.

bcmills commented 10 months ago

(attn @golang/freebsd)

bcmills commented 10 months ago

Note that this probably won't reproduce in the same way with a clang built after https://github.com/llvm/clangir/commit/7440e4ed85aa992718d4b5ccd1c97724bc3bdd2c.

At any rate, this suggests that either there is a bug in Clang's Die function or the sanitizer's use of it (called from here), or something in the Go runtime is preventing Die from exiting with the intended nonzero exit code.

xiaq commented 10 months ago

This is on FreeBSD 14.0 if that matters - I imagine clang is part of the base system and won't change for a release

paulzhol commented 10 months ago

We don't have any builders with anything newer than FreeBSD 13.0/13.1 IIRC.

mknyszek commented 10 months ago

I would be surprised if something in the runtime prevents exiting with a different exit code. The exit coming from the TSAN runtime is probably so hard there's not much we can do about it. (And I don't think we set any libc atexit hooks or anything.)