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/compile: Program should arguably panic, but doesn't #39122

Closed
Merovius opened this issue May 17, 2020 · 2 comments
Closed

cmd/compile: Program should arguably panic, but doesn't #39122

Merovius opened this issue May 17, 2020 · 2 comments

Comments

@Merovius
Copy link

@Merovius Merovius commented May 17, 2020

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

$ go version
go version go1.14.3 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/mero/.cache/go-build"
GOENV="/home/mero/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/mero"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/mero/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/mero/go/pkg/tool/linux_amd64"
GCCGO="/usr/bin/gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build637886539=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I used unsafe to create a []int with len/cap 1 and data pointing at 0:

Program 1

func main() {
	x := *(*[]int)(unsafe.Pointer(&reflect.SliceHeader{Len: 1, Cap: 1}))
	p := &x[0]
	fmt.Println(p, p == nil, interface{}(p) == (*int)(nil))
}

Program 2

func main() {
	x := *(*[]int)(unsafe.Pointer(&reflect.SliceHeader{Len: 1, Cap: 1}))
	p := x[0]
	fmt.Println(p)
}

What did you expect to see?

According to the spec, both programs should panic:

If the evaluation of x would cause a run-time panic, then the evaluation of &x does too.

What did you see instead?

Only Program 2 panics. Also, even though p is nil in Program 1, comparing it to nil evaluates to false. I assume this is due to the compiler seeing how p is initialized and optimizing the comparison out - if you pass it through interface{}, the comparison ends up returning true (presumably fooling this optimization).

Now, arguably it is fine to violate the spec in this case, as we're using unsafe to trick the compiler. I haven't tested if something similar happens if we'd, say, create a PROT_NONE mapping and do the same addressing (I assume it does, though). I just wanted to tell you about it after I found it.

@randall77
Copy link
Contributor

@randall77 randall77 commented May 17, 2020

I used unsafe to create a []int with len/cap 1 and data pointing at 0:

That's not a legal slice. The compiler/runtime assume that a slice with a nonzero length has a non-nil data pointer.

Using unsafe you can always put the system into a weird state it wasn't prepared for. For example, a string with a negative length. Users of unsafe need to be prepared for all kinds of restrictions (that aren't specified anywhere).

I'm going to close this issue. I don't see anything actionable here. Unless you are proposing we remove optimizations to handle weird unsafe cases like this?

I haven't tested if something similar happens if we'd, say, create a PROT_NONE mapping and do the same addressing (I assume it does, though).

The spec makes no promises about non-zero faulting pointers. We currently crash (not panic) if we dereference one.

@randall77 randall77 closed this May 17, 2020
@Merovius
Copy link
Author

@Merovius Merovius commented May 17, 2020

That's fine :) I expected pretty much exactly this, I just wanted to make sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.