Go version

go1.24.4

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2314400207=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/go/keeda/go.mod'
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I have been trying to update our project which uses Go 1.24.1 to 1.24.4 but I see the same issue which I noticed when updating to 1.24.3. The code sample to reproduce the issue was run on the image golang:1.24.4-bookworm.

mkdir keeda && cd keeda
go mod init sanjayts.net/keeda
cat > keeda.go << EOF
package main

/*
#cgo LDFLAGS: -L${SRCDIR} -lkeeda
#include <stdio.h>

int do_it() {
        printf("%s\n", "keeda report");
        return 0;
}
*/
import "C"

import _ "github.com/ebitengine/purego"
import "fmt"

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

func InvokeCGO() string {
        return fmt.Sprintf("answer_from_cgo: %d", C.do_it())
}
EOF
go mod tidy
ASAN_OPTIONS=report_globals=0 go run -asan keeda.go

What did you see happen?

The error message is

link: duplicated definition of symbol github.com/ebitengine/purego.syscall15XABI0, from github.com/ebitengine/purego (type SRODATA size 8) and github.com/ebitengine/purego (type SNOPTRBSS size 64)

What did you expect to see?

I would have expected the code to work as expected and simply output the CGO return value. The output when using 1.24.1 is

keeda report
answer_from_cgo: 0

Comment From: JunyangShao

cc @golang/compiler @cherrymui

Comment From: cherrymui

Okay, one more this... In Go code, it is defined as var syscall15XABI0 uintptr. When building in ASAN mode, it increases the size of global variables to include a red zone, thus type SNOPTRBSS size 64. But this doesn't apply to the definition in the assembly code, which remains at 8. We can't simply choose the Go BSS symbol (we'll lose the content defined in assembly), nor the RODATA assembly symbol (which has the wrong size, which might cause some trouble for ASAN). I guess the easiest way is to choose the RODATA symbol but increase the size.

In general, I think a global variable that is also defined in assembly code is probably not a well-thought case when we introduced ASAN support...