go: runtime/race: ThreadSanitizer failed to allocate 0x0000005c9000 (6066176) bytes at 0x200dc940a0000 (error code: 87)

What version of Go are you using (go version)?

$ go version
go version go1.16.4 windows/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\---\AppData\Local\go-build
set GOENV=C:\Users\---\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=c:\---\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=c:\---
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\---\Go\go1.16.4
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\---\Go\go1.16.4\pkg\tool\windows_amd64
set GOVERSION=go1.16.4
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\---\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\---\AppData\Local\Temp\go-build71564379=/tmp/go-build -gno-record-gcc-switches

What did you do?

Use the source in “Usage” section of https://github.com/go-gl/glfw, then run:

$ go build -race; ./test

What did you expect to see?

The program correctly running, as if -race was not provided.

What did you see instead?

ERROR: ThreadSanitizer failed to allocate 0x0000005c9000 (6066176) bytes at 0x200dc940a0000 (error code: 87)

The error appears on each run. The count, address and error code are always the same. Using different program, the count and address are different.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 14
  • Comments: 51 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Run into this suddenly this week, 10.3.0 isn’t working either. Is there a canonical advised development stack?

Happens with dlv too:

==34372==ERROR: ThreadSanitizer failed to allocate 0x000003061000 (50728960) bytes at 0x200dabe7d0000 (error code: 87)

Very unhelpful error, where is it from? The Go compiler itself?

I was using TDM but it seems dead/unmaintained so I switched to MinGW and that fails too.

Edit:

So this worked for me:

choco install mingw --version 10.2.0 --allow-downgrade

On msys distribution 20210725 we found that downgrading gcc didn’t fix the issue, but downgrading binutils from latest (2.36.1-3 as of our test) to 2.35.1-2 did fix the ThreadSanitizer issue.

My gcc is 10.3.0 (tdm64-1). I also met the same problem. According to the comment, I used binutils 2.33.1 and fixed the issue.

go version go1.17.2 windows/amd64 gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) also OK

The raceinit function @AlexRouSg pointed to calls __tsan_map_shadow after rounding its size parameter to a page. __tsan_map_shadow calls MapShadow. That function gets the actual page size (dwPageSize via GetSystemInfo) and further rounds the start and end points of the region. It then calls MmapFixedSuperNoReserve which calls directly to MmapFixedNoReserve. MmapFixedSuperNoReserve has a “FIXME” comment about using large-page support, but it seems like an invitation to an optimization, not a potential bug. On the first call, MapShadow also calls MmapFixedSuperNoReserve for the “data” segment, with explicit 64k alignment. Since the values in the error messages aren’t 64k aligned, I think that’s not the problematic call.

==5736==ERROR: ThreadSanitizer failed to allocate 0x000000909000 (9474048) bytes at 0x200dd4b374000 (error code: 87)

both of those values are 4k-aligned (and it looks like 4k is the page size on windows).

According to the docs for VirtualAlloc alignment shouldn’t even be necessary - it rounds as necessary, except in the case of MEM_LARGE_PAGES which isn’t in use here.

This is all related to point 1 above. I don’t have a good way to start looking at point 2.

So, a few possibilities here:

  • MS docs are wrong and 64k alignment is required (the comments in the llvm files suggest this!)
  • This memory is already mapped somehow, in a way that makes it invalid (but, I think remapping is OK…)

That first possibility sounds relevant… maybe gcc used to produce 64k-aligned regions in its output, and no longer does?

@benitogf you are out of memory:

1455 | The paging file is too small for this operation to complete. | ERROR_COMMITMENT_LIMIT

c:\program files\x86_64-w64-mingw32-native\include\syslimits.h:12:25: error: no include path in which to search for limits.h 12 | #include_next <limits.h> | ^ (exit status 2)

I think this is getting a bit farther afield from the original issue (“ThreadSanitizer failed to allocate”). Seems like maybe something is out of whack with your gcc installation.

❯ go test -c -o d:\Work\odin\odin\api\src\services\deal__debug_bin.exe -gcflags all=-N -l -v -race . go: unknown flag -l cannot be used with -c

That looks as though the “-l” is being interpreted by the Go command and not passed to the compiler. I would try fixing up your quoting, e.g. “-gcflags all=-N -l” etc.

@ncantelmo that was it, thanks a lot for all the help!

For future reference for anyone else running into this issue with a Chocolatey-installed MinGW:

  • mingw = "10.2.0" works
  • mingw = "10.3.0" fails
  • mingw = "11.X.0" all fail (including 11.3.0)

I think you’ve updated minGW too, that’s what’s causing the issue.

I have had the same problem.

==23768==ERROR: ThreadSanitizer failed to allocate 0x0000016a1000 (23728128) bytes at 0x200d9afc00000 (error code: 87)
exit status 66

This problem carried on with 1.17.x version, however, as @huifly said, downgrading binutils helps so far.

I have been using this custom package from MinGW Distro - nuwen.net, version 17.1 that has gcc 9.2.0 and binutils 2.33.1 bundled and it works with go1.17.6 just fine, however, it appears there are some nice scripts that could enable building custom combination of desired tools so one could have all the packages upgraded while maintaining lower version of binutils.

In addition to that, it is a selfextracting package that only requires setting the path properly, so testing and deploying is rather trivial.