Skip to content

runtime/cgo: pthread attribute object leaked on every new thread on BSD, illumos and AIX #82242

Open

Description

@thevilledev

Go version

go version go1.27.2 openbsd/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/root/go/bin'
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1885286381=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='arm64'
GOHOSTOS='openbsd'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='openbsd'
GOPACKAGESDRIVER=''
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/root/go1.27.2'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/root/go1.27.2/pkg/tool/openbsd_arm64'
GOVCS=''
GOVERSION='go1.27.2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Audited runtime/cgo on OpenBSD/arm64.

runtime/cgo/pthread_unix.c calls pthread_attr_init but never calls pthread_attr_destroy. Several libcs allocate in pthread_attr_init, so every cgo-created thread leaks one heap object.

The non-cgo OpenBSD path in runtime/os_openbsd.go already destroys its attribute object.

Example:

package main

/* static void noop(void) {} */
import "C"
import "runtime"

func main() {
	for range 300_000 {
		done := make(chan struct{})
		go func() {
			runtime.LockOSThread()
			C.noop()
			close(done)
		}()
		<-done
	}
}

Run it:

go build -o leak leak.go
(ulimit -c 0; ulimit -d 65536; ./leak)

What did you see happen?

The native heap grows by about 50 bytes per retired thread. With the ulimit the process aborts with:

runtime: remapping stack memory 0x454428000 32768 a=0x0 err=12
fatal error: remapping stack memory failed
runtime: remapping stack memory 0x454480000 32768 a=0x0 err=12
fatal error: runtime: remapping stack memory 0x45440a000 32768 a=0x0 err=12
fatal error: remapping stack memory failed
remapping stack memory failed

What did you expect to see?

Each successfully init'd attribute should be destroyed after pthread_create. In the example code, the memory usage should plateau and exit without a fault.

I can send a CL.

Activity

  1. gopherbot commented on Oct 15, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/849468 mentions this issue: runtime/cgo: destroy pthread attributes after use

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions