cmd/compile: grow stack before test() to avoid gdb misbehavior

While next-ing over a call in gdb, if execution of that call
causes a goroutine's stack to grow (i.e., be moved), gdb loses
track and runs ahead to the next breakpoint, or to the end of
the program, whichever comes first.

Prevent this by preemptively growing the stack so that
ssa/debug_test.go will reliably measure what is intended,
the goodness of line number placement and variable printing.

Fixes #25497.

Change-Id: I8daf931650292a8c8faad2285d7fd405f2157bd2
Reviewed-on: https://go-review.googlesource.com/114080
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
David Chase 2018-05-22 14:45:27 -04:00
parent 11b3ee6fec
commit 77c51c6c62
15 changed files with 252 additions and 220 deletions

View File

@ -96,4 +96,4 @@
87: if a == 0 { //gdb-opt=(a,n,t) 87: if a == 0 { //gdb-opt=(a,n,t)
88: continue 88: continue
86: for i, a := range hist { 86: for i, a := range hist {
98: } 99: }

View File

@ -148,4 +148,4 @@
86: for i, a := range hist { 86: for i, a := range hist {
87: if a == 0 { //gdb-opt=(a,n,t) 87: if a == 0 { //gdb-opt=(a,n,t)
86: for i, a := range hist { 86: for i, a := range hist {
98: } 99: }

View File

@ -120,4 +120,4 @@ t = 22
87: if a == 0 { //gdb-opt=(a,n,t) 87: if a == 0 { //gdb-opt=(a,n,t)
88: continue 88: continue
86: for i, a := range hist { 86: for i, a := range hist {
98: } 99: }

View File

@ -158,4 +158,4 @@ a = 0
n = 9 n = 9
t = 22 t = 22
86: for i, a := range hist { 86: for i, a := range hist {
98: } 99: }

View File

@ -94,5 +94,13 @@ func test() {
} }
func main() { func main() {
growstack() // Use stack early to prevent growth during test, which confuses gdb
test() test()
} }
var snk string
//go:noinline
func growstack() {
snk = fmt.Sprintf("%#v,%#v,%#v", 1, true, "cat")
}

View File

@ -8,4 +8,4 @@
27: for _, p := range t.stuff { 27: for _, p := range t.stuff {
28: if isFoo(t, p) { 28: if isFoo(t, p) {
29: return 29: return
43: } 44: }

View File

@ -37,7 +37,15 @@ func isFoo(t *thing, b big) bool {
} }
func main() { func main() {
growstack() // Use stack early to prevent growth during test, which confuses gdb
t := &thing{name: "t", self: nil, next: nil, stuff: make([]big, 1)} t := &thing{name: "t", self: nil, next: nil, stuff: make([]big, 1)}
u := thing{name: "u", self: t, next: t, stuff: make([]big, 1)} u := thing{name: "u", self: t, next: t, stuff: make([]big, 1)}
test(t, &u) test(t, &u)
} }
var snk string
//go:noinline
func growstack() {
snk = fmt.Sprintf("%#v,%#v,%#v", 1, true, "cat")
}

View File

@ -4,4 +4,4 @@
10: if err != nil { 10: if err != nil {
14: fmt.Println(pwd) 14: fmt.Println(pwd)
15: } 15: }
19: } 20: }

View File

@ -4,4 +4,4 @@
10: if err != nil { 10: if err != nil {
14: fmt.Println(pwd) 14: fmt.Println(pwd)
15: } 15: }
19: } 20: }

View File

@ -15,5 +15,13 @@ func test() {
} }
func main() { func main() {
growstack() // Use stack early to prevent growth during test, which confuses gdb
test() test()
} }
var snk string
//go:noinline
func growstack() {
snk = fmt.Sprintf("%#v,%#v,%#v", 1, true, "cat")
}

View File

@ -1,56 +1,56 @@
./testdata/scopes.go ./testdata/scopes.go
21: func test() { 22: func test() {
22: x := id(0) 23: x := id(0)
23: y := id(0) 24: y := id(0)
24: fmt.Println(x) 25: fmt.Println(x)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
30: fmt.Println(x, y) 31: fmt.Println(x, y)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
33: a := y 34: a := y
34: f1(a) 35: f1(a)
36: b := 0 37: b := 0
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
39: c := 0 40: c := 0
40: f3(c) 41: f3(c)
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
33: a := y 34: a := y
34: f1(a) 35: f1(a)
36: b := 0 37: b := 0
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
42: c := 1.1 43: c := 1.1
43: f4(int(c)) 44: f4(int(c))
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
52: j = id(1) 53: j = id(1)
53: f = id(2) 54: f = id(2)
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
58: fmt.Println("foo") 59: fmt.Println("foo")
59: break 60: break
63: helloworld() 64: helloworld()
65: } 66: }
14: } 15: }

View File

@ -1,63 +1,63 @@
./testdata/scopes.go ./testdata/scopes.go
21: func test() { 22: func test() {
22: x := id(0) 23: x := id(0)
23: y := id(0) 24: y := id(0)
24: fmt.Println(x) 25: fmt.Println(x)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
30: fmt.Println(x, y) 31: fmt.Println(x, y)
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
30: fmt.Println(x, y) 31: fmt.Println(x, y)
21: func test() { 22: func test() {
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
34: f1(a) 35: f1(a)
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
40: f3(c) 41: f3(c)
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
34: f1(a) 35: f1(a)
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
43: f4(int(c)) 44: f4(int(c))
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
52: j = id(1) 53: j = id(1)
53: f = id(2) 54: f = id(2)
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
58: fmt.Println("foo") 59: fmt.Println("foo")
63: helloworld() 64: helloworld()
65: } 66: }
14: } 15: }

View File

@ -1,64 +1,64 @@
src/cmd/compile/internal/ssa/testdata/scopes.go src/cmd/compile/internal/ssa/testdata/scopes.go
21: func test() { 22: func test() {
22: x := id(0) 23: x := id(0)
23: y := id(0) 24: y := id(0)
24: fmt.Println(x) 25: fmt.Println(x)
0: 0:
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 0 x = 0
y = 0 y = 0
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 1 x = 1
y = 0 y = 0
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 4 x = 4
y = 1 y = 1
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 0 x = 0
y = 5 y = 5
30: fmt.Println(x, y) 31: fmt.Println(x, y)
0: 5 0: 5
33: a := y 34: a := y
34: f1(a) 35: f1(a)
36: b := 0 37: b := 0
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
39: c := 0 40: c := 0
40: f3(c) 41: f3(c)
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
33: a := y 34: a := y
34: f1(a) 35: f1(a)
36: b := 0 37: b := 0
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
42: c := 1.1 43: c := 1.1
43: f4(int(c)) 44: f4(int(c))
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
52: j = id(1) 53: j = id(1)
53: f = id(2) 54: f = id(2)
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
56: j += j * (j ^ 3) / 100 57: j += j * (j ^ 3) / 100
57: if i == f { 58: if i == f {
58: fmt.Println("foo") 59: fmt.Println("foo")
59: break 60: break
63: helloworld() 64: helloworld()
65: } 66: }
14: } 15: }

View File

@ -1,54 +1,54 @@
src/cmd/compile/internal/ssa/testdata/scopes.go src/cmd/compile/internal/ssa/testdata/scopes.go
21: func test() { 22: func test() {
22: x := id(0) 23: x := id(0)
23: y := id(0) 24: y := id(0)
24: fmt.Println(x) 25: fmt.Println(x)
0: 0:
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 0 x = 0
y = 0 y = 0
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 1 x = 1
y = 0 y = 0
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
26: x := i * i 27: x := i * i
27: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y) 28: y += id(x) //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 4 x = 4
y = 1 y = 1
25: for i := x; i < 3; i++ { 26: for i := x; i < 3; i++ {
30: fmt.Println(x, y) 31: fmt.Println(x, y)
29: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y) 30: y = x + y //gdb-dbg=(x,y)//gdb-opt=(x,y)
x = 0 x = 0
y = 5 y = 5
0: 5 0: 5
34: f1(a) 35: f1(a)
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
40: f3(c) 41: f3(c)
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
34: f1(a) 35: f1(a)
37: f2(b) 38: f2(b)
38: if gretbool() { 39: if gretbool() {
43: f4(int(c)) 44: f4(int(c))
45: f5(b) 46: f5(b)
47: f6(a) 48: f6(a)
32: for x := 0; x <= 1; x++ { // From delve scopetest.go 33: for x := 0; x <= 1; x++ { // From delve scopetest.go
52: j = id(1) 53: j = id(1)
53: f = id(2) 54: f = id(2)
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
61: sleepytime() 62: sleepytime()
55: for i := 0; i <= 5; i++ { 56: for i := 0; i <= 5; i++ {
57: if i == f { 58: if i == f {
58: fmt.Println("foo") 59: fmt.Println("foo")
63: helloworld() 64: helloworld()
65: } 66: }
14: } 15: }

View File

@ -10,6 +10,7 @@ import (
) )
func main() { func main() {
growstack() // Use stack early to prevent growth during test, which confuses gdb
test() test()
} }
@ -97,3 +98,10 @@ func gretbool() bool {
boolvar = !boolvar boolvar = !boolvar
return x return x
} }
var sink string
//go:noinline
func growstack() {
sink = fmt.Sprintf("%#v,%#v,%#v", 1, true, "cat")
}