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.

Comment From: evanj

Maybe related to https://github.com/golang/go/issues/61229 , which fixed very similar crashes when Apple introduced clang version 15

Comment From: cherrymui

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.

Comment From: steffenfritz

The classic linker is not available anymore on MacOS 14.5

Comment From: gopherbot

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

Comment From: cherrymui

@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.)

Comment From: gopherbot

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.

Comment From: gopherbot

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

Comment From: gopherbot

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