Commit 77c51c6c authored by David Chase's avatar David Chase

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: default avatarAustin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 11b3ee6f
...@@ -96,4 +96,4 @@ ...@@ -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: }
...@@ -148,4 +148,4 @@ ...@@ -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: }
...@@ -120,4 +120,4 @@ t = 22 ...@@ -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: }
...@@ -158,4 +158,4 @@ a = 0 ...@@ -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: }
...@@ -94,5 +94,13 @@ func test() { ...@@ -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")
}
...@@ -8,4 +8,4 @@ ...@@ -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: }
...@@ -37,7 +37,15 @@ func isFoo(t *thing, b big) bool { ...@@ -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")
}
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
10: if err != nil { 10: if err != nil {
14: fmt.Println(pwd) 14: fmt.Println(pwd)
15: } 15: }
19: } 20: }
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
10: if err != nil { 10: if err != nil {
14: fmt.Println(pwd) 14: fmt.Println(pwd)
15: } 15: }
19: } 20: }
...@@ -15,5 +15,13 @@ func test() { ...@@ -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")
}
./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: }
./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: }
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: }
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: }
...@@ -10,6 +10,7 @@ import ( ...@@ -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 { ...@@ -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")
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment