Skip to content
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

cmd/cgo: Cgo uint32 -> unsafe.Pointer -> C.ulong conversion fails. #50100

Closed
ibd1279 opened this issue Dec 10, 2021 · 5 comments
Closed

cmd/cgo: Cgo uint32 -> unsafe.Pointer -> C.ulong conversion fails. #50100

ibd1279 opened this issue Dec 10, 2021 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@ibd1279
Copy link

ibd1279 commented Dec 10, 2021

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

go version go1.17.5 darwin/amd64

Does this issue reproduce with the latest release?

Was able to reproduce the issue using go1.17.5

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jwatson/Library/Caches/go-build"
GOENV="/Users/jwatson/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/jwatson/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/jwatson/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17.5"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/jwatson/Documents/go/cgotest/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8n/lk2hpm7562nb_pp_7vxxc_hw0000gn/T/go-build729837254=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I created a uint32, took it's address, converted the address into an unsafe.Pointer, and then converted the unsafe.Pointer into a *C.ulong. The dereferenced to a C.ulong.
https://gist.github.com/ibd1279/1edb2726f69dbd17f77a8a7657c790b4

What did you expect to see?

I expect to see the value of the uint32 and the C.ulong always be the same.

What did you see instead?

In some number of cases, the value cast through the pointer does not match the value directly cast. Running the attached program on my computer I get his output:
0 iteration : 1053, 0xc00001806c, 0xc00001806c, 0xc00001806c, 4294968349, 1053
2004 iteration : 1053, 0xc000019ffc, 0xc000019ffc, 0xc000019ffc, 5571591916090295325, 1053

Someone else running the same application on a newer M1 mac, using go1.17.3 from homebrew received the following output
0 iteration : 1053, 0xc00001a07c, 0xc00001a07c, 0xc00001a07c, 4294968349, 1053
2000 iteration : 1053, 0xc00001bffc, 0xc00001bffc, 0xc00001bffc, 5571591916090295325, 1053

I was also able to reproduce it on go version go1.13.8 linux/amd64 and go version go1.17.5 linux/amd64

@toothrot toothrot changed the title affected/package: Cgo uint32 -> unsafe.Pointer -> C.ulong conversion fails. cmd/cgo: Cgo uint32 -> unsafe.Pointer -> C.ulong conversion fails. Dec 10, 2021
@toothrot toothrot added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 10, 2021
@toothrot toothrot added this to the Backlog milestone Dec 10, 2021
@cherrymui
Copy link
Member

C ulong is unsigned long which is 64-bit on some platforms. This works as intended. Thanks.

@ibd1279
Copy link
Author

ibd1279 commented Dec 10, 2021

The expected behavior is to sometimes fail to convert the value, and sometimes not, on the same platform, same os, and same application invocation?

Maybe my example isn't clear. Running the example does the conversion 10k times in a loop, the conversion regularly fails only two out of 10k times. Is the 2 times the works as expected or are the 9.998k times works as expected? Either way, isn't the unexpected set a bug?

@cherrymui
Copy link
Member

When ulong is 64-bit, the code is converting a pointer to a 32-bit object to a 64-bit object, which is not a valid use of unsafe.Pointer. See https://pkg.go.dev/unsafe#Pointer

If you run the code with unsafe pointer checking enabled (-race or -gcflags=-d=checkptr=1), it will always emit an error.

@ibd1279
Copy link
Author

ibd1279 commented Dec 10, 2021

Ah, you are right. Is there an effective way to detect the size of C.ulong across platforms?

@randall77
Copy link
Contributor

unsafe.Sizeof(C.ulong(0))

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants