@@ -22,24 +22,27 @@ import (
22
22
"time"
23
23
)
24
24
25
- var update = flag .Bool ("u" , false , "update test reference files" )
26
- var verbose = flag .Bool ("v" , false , "print debugger interactions (very verbose)" )
27
- var dryrun = flag .Bool ("n" , false , "just print the command line and first debugging bits" )
28
- var useDelve = flag .Bool ("d" , false , "use Delve (dlv) instead of gdb, use dlv reverence files" )
29
- var force = flag .Bool ("f" , false , "force run under not linux-amd64; also do not use tempdir" )
30
-
31
- var repeats = flag .Bool ("r" , false , "detect repeats in debug steps and don't ignore them" )
32
- var inlines = flag .Bool ("i" , false , "do inlining for gdb (makes testing flaky till inlining info is correct)" )
33
-
34
- var hexRe = regexp .MustCompile ("0x[a-zA-Z0-9]+" )
35
- var numRe = regexp .MustCompile ("-?[0-9]+" )
36
- var stringRe = regexp .MustCompile ("\" ([^\\ \" ]|(\\ .))*\" " )
37
- var leadingDollarNumberRe = regexp .MustCompile ("^[$][0-9]+" )
38
- var optOutGdbRe = regexp .MustCompile ("[<]optimized out[>]" )
39
- var numberColonRe = regexp .MustCompile ("^ *[0-9]+:" )
25
+ var (
26
+ update = flag .Bool ("u" , false , "update test reference files" )
27
+ verbose = flag .Bool ("v" , false , "print debugger interactions (very verbose)" )
28
+ dryrun = flag .Bool ("n" , false , "just print the command line and first debugging bits" )
29
+ useGdb = flag .Bool ("g" , false , "use Gdb instead of Delve (dlv), use gdb reference files" )
30
+ force = flag .Bool ("f" , false , "force run under not linux-amd64; also do not use tempdir" )
31
+ repeats = flag .Bool ("r" , false , "detect repeats in debug steps and don't ignore them" )
32
+ inlines = flag .Bool ("i" , false , "do inlining for gdb (makes testing flaky till inlining info is correct)" )
33
+ )
34
+
35
+ var (
36
+ hexRe = regexp .MustCompile ("0x[a-zA-Z0-9]+" )
37
+ numRe = regexp .MustCompile ("-?[0-9]+" )
38
+ stringRe = regexp .MustCompile ("\" ([^\\ \" ]|(\\ .))*\" " )
39
+ leadingDollarNumberRe = regexp .MustCompile ("^[$][0-9]+" )
40
+ optOutGdbRe = regexp .MustCompile ("[<]optimized out[>]" )
41
+ numberColonRe = regexp .MustCompile ("^ *[0-9]+:" )
42
+ )
40
43
41
44
var gdb = "gdb" // Might be "ggdb" on Darwin, because gdb no longer part of XCode
42
- var debugger = "gdb " // For naming files, etc.
45
+ var debugger = "dlv " // For naming files, etc.
43
46
44
47
var gogcflags = os .Getenv ("GO_GCFLAGS" )
45
48
@@ -98,23 +101,18 @@ func TestNexting(t *testing.T) {
98
101
}
99
102
testenv .MustHaveGoBuild (t )
100
103
101
- if ! * useDelve && ! * force && ! (runtime .GOOS == "linux" && runtime .GOARCH == "amd64" ) {
104
+ if * useGdb && ! * force && ! (runtime .GOOS == "linux" && runtime .GOARCH == "amd64" ) {
102
105
// Running gdb on OSX/darwin is very flaky.
103
106
// Sometimes it is called ggdb, depending on how it is installed.
104
107
// It also sometimes requires an admin password typed into a dialog box.
105
108
// Various architectures tend to differ slightly sometimes, and keeping them
106
109
// all in sync is a pain for people who don't have them all at hand,
107
110
// so limit testing to amd64 (for now)
108
- skipReasons += "not run unless linux-amd64 or -d (delve) or -f (force); "
111
+ skipReasons += "not run when testing gdb (-g) unless forced (-f) or linux-amd64 "
109
112
}
110
113
111
- if * useDelve {
112
- debugger = "dlv"
113
- _ , err := exec .LookPath ("dlv" )
114
- if err != nil {
115
- skipReasons += "not run because dlv (requested by -d option) not on path; "
116
- }
117
- } else {
114
+ if * useGdb {
115
+ debugger = "gdb"
118
116
_ , err := exec .LookPath (gdb )
119
117
if err != nil {
120
118
if runtime .GOOS != "darwin" {
@@ -123,12 +121,18 @@ func TestNexting(t *testing.T) {
123
121
// On Darwin, MacPorts installs gdb as "ggdb".
124
122
_ , err = exec .LookPath ("ggdb" )
125
123
if err != nil {
126
- skipReasons += "not run because gdb (and also ggdb) not on path; "
124
+ skipReasons += "not run because gdb (and also ggdb) request by -g option not on path; "
127
125
} else {
128
126
gdb = "ggdb"
129
127
}
130
128
}
131
129
}
130
+ } else { // Delve
131
+ debugger = "dlv"
132
+ _ , err := exec .LookPath ("dlv" )
133
+ if err != nil {
134
+ skipReasons += "not run because dlv not on path; "
135
+ }
132
136
}
133
137
134
138
if skipReasons != "" {
@@ -137,14 +141,14 @@ func TestNexting(t *testing.T) {
137
141
138
142
optFlags := "" // Whatever flags are needed to test debugging of optimized code.
139
143
dbgFlags := "-N -l"
140
- if ! * useDelve && ! * inlines {
144
+ if * useGdb && ! * inlines {
141
145
// For gdb (default), disable inlining so that a compiler test does not depend on library code.
142
- // TODO: Technically not necessary in 1.10, but it causes a largish regression that needs investigation.
146
+ // TODO: Technically not necessary in 1.10 and later , but it causes a largish regression that needs investigation.
143
147
optFlags += " -l"
144
148
}
145
149
146
150
moreargs := []string {}
147
- if ! * useDelve && (runtime .GOOS == "darwin" || runtime .GOOS == "windows" ) {
151
+ if * useGdb && (runtime .GOOS == "darwin" || runtime .GOOS == "windows" ) {
148
152
// gdb and lldb on Darwin do not deal with compressed dwarf.
149
153
// also, Windows.
150
154
moreargs = append (moreargs , "-ldflags=-compressdwarf=false" )
@@ -158,7 +162,12 @@ func TestNexting(t *testing.T) {
158
162
159
163
optSubTest (t , debugger + "-opt" , "hist" , optFlags , 1000 , moreargs ... )
160
164
optSubTest (t , debugger + "-opt" , "scopes" , optFlags , 1000 , moreargs ... )
161
- optSubTest (t , debugger + "-opt" , "infloop" , optFlags , 10 , moreargs ... )
165
+
166
+ // Was optSubtest, this test is observed flaky on Linux in Docker on (busy) macOS, probably because of timing
167
+ // glitches in this harness.
168
+ // TODO get rid of timing glitches in this harness.
169
+ skipSubTest (t , debugger + "-opt" , "infloop" , optFlags , 10 , moreargs ... )
170
+
162
171
}
163
172
164
173
// subTest creates a subtest that compiles basename.go with the specified gcflags and additional compiler arguments,
@@ -172,6 +181,17 @@ func subTest(t *testing.T, tag string, basename string, gcflags string, moreargs
172
181
})
173
182
}
174
183
184
+ // skipSubTest is the same as subTest except that it skips the test if execution is not forced (-f)
185
+ func skipSubTest (t * testing.T , tag string , basename string , gcflags string , count int , moreargs ... string ) {
186
+ t .Run (tag + "-" + basename , func (t * testing.T ) {
187
+ if * force {
188
+ testNexting (t , basename , tag , gcflags , count , moreargs ... )
189
+ } else {
190
+ t .Skip ("skipping flaky test becaused not forced (-f)" )
191
+ }
192
+ })
193
+ }
194
+
175
195
// optSubTest is the same as subTest except that it skips the test if the runtime and libraries
176
196
// were not compiled with optimization turned on. (The skip may not be necessary with Go 1.10 and later)
177
197
func optSubTest (t * testing.T , tag string , basename string , gcflags string , count int , moreargs ... string ) {
@@ -218,10 +238,10 @@ func testNexting(t *testing.T, base, tag, gcflags string, count int, moreArgs ..
218
238
nextlog := testbase + ".nexts"
219
239
tmplog := tmpbase + ".nexts"
220
240
var dbg dbgr
221
- if * useDelve {
222
- dbg = newDelve (tag , exe )
223
- } else {
241
+ if * useGdb {
224
242
dbg = newGdb (tag , exe )
243
+ } else {
244
+ dbg = newDelve (tag , exe )
225
245
}
226
246
h1 := runDbgr (dbg , count )
227
247
if * dryrun {
@@ -539,7 +559,7 @@ func (s *delveState) start() {
539
559
panic (fmt .Sprintf ("There was an error [start] running '%s', %v\n " , line , err ))
540
560
}
541
561
s .ioState .readExpecting (- 1 , 5000 , "Type 'help' for list of commands." )
542
- expect ( "Breakpoint [0-9]+ set at " , s .ioState .writeReadExpect ("b main.test\n " , "[(]dlv[)] " ) )
562
+ s .ioState .writeReadExpect ("b main.test\n " , "[(]dlv[)] " )
543
563
s .stepnext ("c" )
544
564
}
545
565
@@ -598,7 +618,7 @@ func (s *gdbState) start() {
598
618
line := asCommandLine ("" , s .cmd )
599
619
panic (fmt .Sprintf ("There was an error [start] running '%s', %v\n " , line , err ))
600
620
}
601
- s .ioState .readExpecting ( - 1 , - 1 , "[(]gdb[)] " )
621
+ s .ioState .readSimpleExpecting ( "[(]gdb[)] " )
602
622
x := s .ioState .writeReadExpect ("b main.test\n " , "[(]gdb[)] " )
603
623
expect ("Breakpoint [0-9]+ at" , x )
604
624
s .stepnext (run )
@@ -840,7 +860,7 @@ func (s *ioState) writeReadExpect(ss, expectRE string) tstring {
840
860
if err != nil {
841
861
panic (fmt .Sprintf ("There was an error writing '%s', %v\n " , ss , err ))
842
862
}
843
- return s .readExpecting ( - 1 , - 1 , expectRE )
863
+ return s .readSimpleExpecting ( expectRE )
844
864
}
845
865
846
866
func (s * ioState ) readExpecting (millis , interlineTimeout int , expectedRE string ) tstring {
@@ -887,6 +907,40 @@ loop:
887
907
return s .last
888
908
}
889
909
910
+ func (s * ioState ) readSimpleExpecting (expectedRE string ) tstring {
911
+ s .last = tstring {}
912
+ var re * regexp.Regexp
913
+ if expectedRE != "" {
914
+ re = regexp .MustCompile (expectedRE )
915
+ }
916
+ for {
917
+ select {
918
+ case x , ok := <- s .outChan :
919
+ if ! ok {
920
+ s .outChan = nil
921
+ }
922
+ s .last .o += x
923
+ case x , ok := <- s .errChan :
924
+ if ! ok {
925
+ s .errChan = nil
926
+ }
927
+ s .last .e += x
928
+ }
929
+ if re != nil {
930
+ if re .MatchString (s .last .o ) {
931
+ break
932
+ }
933
+ if re .MatchString (s .last .e ) {
934
+ break
935
+ }
936
+ }
937
+ }
938
+ if * verbose {
939
+ fmt .Printf ("<= %s%s" , s .last .o , s .last .e )
940
+ }
941
+ return s .last
942
+ }
943
+
890
944
// replaceEnv returns a new environment derived from env
891
945
// by removing any existing definition of ev and adding ev=evv.
892
946
func replaceEnv (env []string , ev string , evv string ) []string {
0 commit comments