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: missing inlined stack trace frame in index panic #29504

Open
rsc opened this Issue Jan 2, 2019 · 1 comment

Comments

Projects
None yet
2 participants
@rsc
Copy link
Contributor

rsc commented Jan 2, 2019

I have a (boiled down) very simple program. main calls f calls g. g calls h and indexes into an empty slice using the result of h.

I expect the index out of range stack trace to show the index panic happen in g, called from f, called from main. And it does:

$ cat >x.go <<EOF
package main
type T = [1]byte
var x []T
func main() { f() }
func f() T { return g() }
func g() T { return x[h()] }
func h() int { return 9 }
EOF
$ go run x.go
panic: runtime error: index out of range

goroutine 1 [running]:
main.g(...)
	/Users/rsc/x.go:6
main.f(...)
	/Users/rsc/x.go:5
main.main()
	/Users/rsc/x.go:4 +0x24
exit status 2
$ 

This is correct.

But now I change the thing being indexed from a slice of 1-bytes to a slice of 2-bytes:

$ sed s/1/2/ x.go >y.go
$ go run y.go
panic: runtime error: index out of range

goroutine 1 [running]:
main.f(...)
	/Users/rsc/y.go:5
main.main()
	/Users/rsc/y.go:4 +0x24
exit status 2
$ 

The stack trace no longer shows g. This is not correct.

In the actual program where this came up, my slice was of [32]byte. Changing to slice of int also restores the stack trace. But something about indexing into a slice containing multibyte arrays is breaking the inlined stack trace information for an index panic for that operation.

/cc @randall77 @aclements

@rsc rsc added this to the Go1.13 milestone Jan 2, 2019

@randall77

This comment has been minimized.

Copy link
Contributor

randall77 commented Jan 3, 2019

Looks like we're not pulling the line numbers from quite the right place.
There's an ~r0 = INDEX x y node. When we build the bounds check, we end up using the line number of the =, not of the INDEX. The line number of the = is at line 8 because it's built by the inlining pass (it's at the call site, not the body). We just need to pull from the INDEX instead, which is correctly labeled at line 9.

The [1] version works correctly because that's a different path through the ssa builder that happens to work.

We should pass an explicit source position to all the panic-call-generating routines. Currently it just grabs the line number from the last-processed node, which is fragile.

@randall77 randall77 self-assigned this Jan 3, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.