Skip to content

cmd/link: using -fuzz with test that links with cgo on darwin causes linker failure #65169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
evanj opened this issue Jan 19, 2024 · 8 comments
Closed
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@evanj
Copy link
Contributor

evanj commented Jan 19, 2024

Go version

go1.21.6, go1.22rc1

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/evan.jones/Library/Caches/go-build'
GOENV='/Users/evan.jones/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/evan.jones/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/evan.jones/go'
GOPRIVATE=''
GOPROXY=''
GOROOT='/opt/homebrew/Cellar/go/1.21.6/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.21.6/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/evan.jones/cgofuzzstaticlinkbug/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 -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/g1/97d8s0r57hj4nv4_qd3fqcrm0000gp/T/go-build397391104=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Run the following package with go test . -fuzz=Fuzz on Mac OS X and it prints a linker failure with both go1.21.6 and go1.22rc1. Using go run or go test without fuzzing works fine.

cgofuzz.go

package main

// const char* cgoString() { return "cgo"; }
import "C"
import "fmt"

func cgoString() string {
	return C.GoString(C.cgoString())
}

func main() {
	fmt.Printf("cgoString: %s\n", cgoString())
}

cgofuzz_test.go

package main

import (
	"testing"
)

func FuzzSomething(f *testing.F) {
	f.Add(0)
	f.Fuzz(func(t *testing.T, x int) {})
}

What did you see happen?

/opt/homebrew/Cellar/go/1.21.6/libexec/pkg/tool/darwin_arm64/link: running cc failed: exit status 1
0  0x102882f2c  __assert_rtn + 72
1  0x10283ba20  ___ZN2ld16LayoutExecutable27writeContentWithoutLinkEditENSt3__14spanIhLm18446744073709551615EEEy_block_invoke_2 + 0
2  0x18b088950  _dispatch_client_callout2 + 20
3  0x18b09d1a4  _dispatch_apply_invoke_and_wait + 176
4  0x18b09c464  _dispatch_apply_with_attr_f + 1176
5  0x18b09c650  dispatch_apply + 96
6  0x10283bba4  void mapReduce<ld::Atom const*, mach_o::Error>(std::__1::span<ld::Atom const*, 18446744073709551615ul>, unsigned long, void (unsigned long, mach_o::Error&, std::__1::span<ld::Atom const*, 18446744073709551615ul>) block_pointer, void (std::__1::span<mach_o::Error, 18446744073709551615ul>) block_pointer) + 336
7  0x10283b754  ld::LayoutExecutable::writeContentWithoutLinkEdit(std::__1::span<unsigned char, 18446744073709551615ul>, unsigned long long) + 1180
8  0x102840ebc  ld::LayoutExecutable::writeToFile(char const*) + 14444
9  0x1027f2c80  main + 9628
ld: Assertion failed: (addr + content.size() <= sectionEndAddr), function writeContentWithoutLinkEdit_block_invoke, file Layout.cpp, line 5960.
clang: error: linker command failed with exit code 1 (use -v to see invocation)

What did you expect to see?

I expected the test to run in fuzzing mode.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 19, 2024
@evanj
Copy link
Contributor Author

evanj commented Jan 19, 2024

Maybe related to #61229 , which fixed very similar crashes when Apple introduced clang version 15

@cherrymui
Copy link
Member

Thanks for reporting. I can reproduce the failure. This looks like a bug in Apple's new linker. I'll look into it and report it to Apple. In the mean time, you can work around by using the old Apple linker, by passing the -ldflags=-extldflags=-Wl,-ld_classic flag to go test.

@cherrymui cherrymui added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 23, 2024
@cherrymui cherrymui added this to the Go1.23 milestone Jan 23, 2024
@steffenfritz
Copy link

steffenfritz commented Jun 1, 2024

The classic linker is not available anymore on MacOS 14.5

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/592095 mentions this issue: cmd/link: put runtime.end in the last section of data segment

@cherrymui
Copy link
Member

@gopherbot please backport this to previous releases. This causes build failure when using fuzzing with cgo. (There is a workaround, by specifying the old Apple linker, but that is not great.)

@gopherbot
Copy link
Contributor

Backport issue(s) opened: #67944 (for 1.21), #67945 (for 1.22).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jun 12, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/592477 mentions this issue: [release-branch.go1.21 cmd/link: put runtime.end in the last section of data segment

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/592478 mentions this issue: [release-branch.go1.22] cmd/link: put runtime.end in the last section of data segment

gopherbot pushed a commit that referenced this issue Jun 24, 2024
… of data segment

Currently the runtime.end symbol is put into the noptrbss section,
which is usually the last section, except that when fuzzing is
enabled, the last section is actually .go.fuzzcntrs. The
runtime.end symbol has the value pointing to the end of the data
segment, so if it is not in the last section, the value will not
actually be in the range of the section. This causes an assertion
failure in the new Apple linker. This CL fixes this by putting it
in the last section.

Updates #65169.
Fixes #67944.

Change-Id: I5c991c46a0483a96e5f6e0255a3b444953676026
Reviewed-on: https://go-review.googlesource.com/c/go/+/592095
Reviewed-by: Than McIntosh <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
(cherry picked from commit b589478)
Reviewed-on: https://go-review.googlesource.com/c/go/+/592477
gopherbot pushed a commit that referenced this issue Jun 24, 2024
… of data segment

Currently the runtime.end symbol is put into the noptrbss section,
which is usually the last section, except that when fuzzing is
enabled, the last section is actually .go.fuzzcntrs. The
runtime.end symbol has the value pointing to the end of the data
segment, so if it is not in the last section, the value will not
actually be in the range of the section. This causes an assertion
failure in the new Apple linker. This CL fixes this by putting it
in the last section.

Updates #65169.
Fixes #67945.

Change-Id: I5c991c46a0483a96e5f6e0255a3b444953676026
Reviewed-on: https://go-review.googlesource.com/c/go/+/592095
Reviewed-by: Than McIntosh <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
(cherry picked from commit b589478)
Reviewed-on: https://go-review.googlesource.com/c/go/+/592478
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Projects
Development

No branches or pull requests

5 participants