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: seg fault with -ssa=1 #16727

Closed
edressel opened this issue Aug 16, 2016 · 5 comments
Closed

cmd/compile: seg fault with -ssa=1 #16727

edressel opened this issue Aug 16, 2016 · 5 comments

Comments

@edressel
Copy link

Please answer these questions before submitting your issue. Thanks!

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

go version go1.7 linux/amd64

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/eliot/gopath"
GORACE=""
GOROOT="/home/eliot/go"
GOTOOLDIR="/home/eliot/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build796172607=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

  1. What did you do?
    If possible, provide a recipe for reproducing the error.
    A complete runnable program is good.
    A link on play.golang.org is best.

https://play.golang.org/p/OVfeAp_FIG

segfaults with -ssa=1; works with -ssa=0

both crash0() and crash1() cause segfaults

  1. What did you expect to see?
  2. What did you see instead?
@bradfitz bradfitz changed the title seg fault with -ssa=1 cmd/compile: seg fault with -ssa=1 Aug 16, 2016
@bradfitz
Copy link
Contributor

/cc @randall77 @cherrymui @dr2chase

@bradfitz bradfitz added this to the Go1.7.1 milestone Aug 16, 2016
@randall77
Copy link
Contributor

I think this is a bug in your code.
You're casting (using unsafe) a pointer to an empty struct to a pointer to a large data structure. This is the fundamental error.

The old legacy backend and the SSA backend differ in how they respond to this bad code.
As part of the expression r.bars[0][0].Offset(), you're getting a nil check on p+65536. The old compiler did a nil check with a compare against 0, which passes. The new compiler does a test load off of that pointer, which fails because it points to the middle of nowhere (way outside the bounds of the original &struct{}{} you allocated).

@bradfitz bradfitz removed this from the Go1.7.1 milestone Aug 16, 2016
@edressel
Copy link
Author

Understood about the pointer pointing to nowhere. But I never actually dereference the pointer only
compute its offset from the base. Is this still a bug? Not sure I understand the semantics of unsafe
here. FYI the code involves a large memory mapped ASIC and Offset() is used to compute register/memory offsets within the ASIC. With go 1.6 everything works like a charm (as with -ssa=0).

Do I need to find another way to make Offset() work?

@randall77
Copy link
Contributor

The semantics of unsafe are intentionally left vague. Hence the name. That gives us wiggle room to modify how things work under the covers, but it means you can get bitten by assumptions that don't hold from release to release. Sorry about that.

Can you use unsafe.Offsetof? As in

    addr := ASICbase + unsafe.Offsetof(foo_regs{}.bars)

@edressel
Copy link
Author

No worries re: unsafe. Just coded up mmap based solution. Works like a charm with ssa.

unsafe.Offsets(r.bars[0][0][0]) is invalid syntax. Bummer. I did try that. Only works for struct.field

I'm cool with the mmap since /dev/zero mapped memory is copy on write via the linux kernel & we never write. so, mmap'ing e.g. 2^N bytes N = #address bits is no problem. Do, let me know if you can think of a better solution.

Hey, and thanks for all the great compiler work... been following along for a while on dev.ssa

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants