Skip to content

Commit 1099644

Browse files
committed
cmd/compile: add ability to print extra information in bisect output
Change-Id: I619c21ab9754f67b69215cfed238a3e489c7fbcf Reviewed-on: https://go-review.googlesource.com/c/go/+/493955 Reviewed-by: David Chase <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Russ Cox <[email protected]>
1 parent 3d33532 commit 1099644

File tree

5 files changed

+45
-41
lines changed

5 files changed

+45
-41
lines changed

src/cmd/compile/internal/base/hashdebug.go

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ var LoopVarHash *HashDebug // for debugging shared/private loop variable changes
122122
// 6. gossahash should return a single function whose miscompilation
123123
// causes the problem, and you can focus on that.
124124
func DebugHashMatchPkgFunc(pkg, fn string) bool {
125-
return hashDebug.MatchPkgFunc(pkg, fn)
125+
return hashDebug.MatchPkgFunc(pkg, fn, nil)
126126
}
127127

128128
func DebugHashMatchPos(pos src.XPos) bool {
129-
return hashDebug.MatchPos(pos)
129+
return hashDebug.MatchPos(pos, nil)
130130
}
131131

132132
// HasDebugHash returns true if Flags.Gossahash is non-empty, which
@@ -247,62 +247,66 @@ func (d *HashDebug) match(hash uint64) *hashAndMask {
247247
// representation of the hash of pkg and fn. If the variable is not nil,
248248
// then a true result is accompanied by stylized output to d.logfile, which
249249
// is used for automated bug search.
250-
func (d *HashDebug) MatchPkgFunc(pkg, fn string) bool {
250+
func (d *HashDebug) MatchPkgFunc(pkg, fn string, note func() string) bool {
251251
if d == nil {
252252
return true
253253
}
254254
// Written this way to make inlining likely.
255-
return d.matchPkgFunc(pkg, fn)
255+
return d.matchPkgFunc(pkg, fn, note)
256256
}
257257

258-
func (d *HashDebug) matchPkgFunc(pkg, fn string) bool {
258+
func (d *HashDebug) matchPkgFunc(pkg, fn string, note func() string) bool {
259259
hash := bisect.Hash(pkg, fn)
260-
if d.bisect != nil {
261-
if d.bisect.ShouldPrint(hash) {
262-
d.log(d.name, hash, pkg+"."+fn)
263-
}
264-
return d.bisect.ShouldEnable(hash)
265-
}
266-
267-
// TODO: Delete rest of function body when we switch to bisect-only.
268-
if m := d.match(hash); m != nil {
269-
d.log(m.name, hash, pkg+"."+fn)
270-
return true
271-
}
272-
return false
260+
return d.matchAndLog(hash, func() string { return pkg + "." + fn }, note)
273261
}
274262

275263
// MatchPos is similar to MatchPkgFunc, but for hash computation
276264
// it uses the source position including all inlining information instead of
277265
// package name and path.
278266
// Note that the default answer for no environment variable (d == nil)
279267
// is "yes", do the thing.
280-
func (d *HashDebug) MatchPos(pos src.XPos) bool {
268+
func (d *HashDebug) MatchPos(pos src.XPos, desc func() string) bool {
281269
if d == nil {
282270
return true
283271
}
284272
// Written this way to make inlining likely.
285-
return d.matchPos(Ctxt, pos)
273+
return d.matchPos(Ctxt, pos, desc)
286274
}
287275

288-
func (d *HashDebug) matchPos(ctxt *obj.Link, pos src.XPos) bool {
276+
func (d *HashDebug) matchPos(ctxt *obj.Link, pos src.XPos, note func() string) bool {
289277
hash := d.hashPos(ctxt, pos)
278+
return d.matchAndLog(hash, func() string { return d.fmtPos(ctxt, pos) }, note)
279+
}
290280

281+
// matchAndLog is the core matcher. It reports whether the hash matches the pattern.
282+
// If a report needs to be printed, match prints that report to the log file.
283+
// The text func must be non-nil and should return a user-readable
284+
// representation of what was hashed. The note func may be nil; if non-nil,
285+
// it should return additional information to display to the user when this
286+
// change is selected.
287+
func (d *HashDebug) matchAndLog(hash uint64, text, note func() string) bool {
291288
if d.bisect != nil {
292289
if d.bisect.ShouldPrint(hash) {
293-
d.log(d.name, hash, d.fmtPos(ctxt, pos))
290+
var t string
291+
if !d.bisect.MarkerOnly() {
292+
t = text()
293+
if note != nil {
294+
if n := note(); n != "" {
295+
t += ": " + n
296+
}
297+
}
298+
}
299+
d.log(d.name, hash, t)
294300
}
295301
return d.bisect.ShouldEnable(hash)
296302
}
297303

298304
// TODO: Delete rest of function body when we switch to bisect-only.
299-
300-
// Return false for explicitly excluded hashes
301305
if d.excluded(hash) {
302306
return false
303307
}
304308
if m := d.match(hash); m != nil {
305-
d.log(m.name, hash, d.fmtPos(ctxt, pos))
309+
d.log(m.name, hash, text())
306310
return true
307311
}
308312
return false

src/cmd/compile/internal/base/hashdebug_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestHashDebugGossahashY(t *testing.T) {
1616
if hd == nil {
1717
t.Errorf("NewHashDebug should not return nil for GOSSASHASH=y")
1818
}
19-
if !hd.MatchPkgFunc("anything", "anyfunc") {
19+
if !hd.MatchPkgFunc("anything", "anyfunc", nil) {
2020
t.Errorf("NewHashDebug should return yes for everything for GOSSASHASH=y")
2121
}
2222
}
@@ -26,7 +26,7 @@ func TestHashDebugGossahashN(t *testing.T) {
2626
if hd == nil {
2727
t.Errorf("NewHashDebug should not return nil for GOSSASHASH=n")
2828
}
29-
if hd.MatchPkgFunc("anything", "anyfunc") {
29+
if hd.MatchPkgFunc("anything", "anyfunc", nil) {
3030
t.Errorf("NewHashDebug should return no for everything for GOSSASHASH=n")
3131
}
3232
}
@@ -60,21 +60,21 @@ func TestHash(t *testing.T) {
6060

6161
func TestHashMatch(t *testing.T) {
6262
b := new(bytes.Buffer)
63-
hd := NewHashDebug("GOSSAHASH", "1110", b)
64-
check := hd.MatchPkgFunc("bar", "0")
63+
hd := NewHashDebug("GOSSAHASH", "v1110", b)
64+
check := hd.MatchPkgFunc("bar", "0", func() string { return "note" })
6565
msg := b.String()
6666
t.Logf("message was '%s'", msg)
6767
if !check {
6868
t.Errorf("GOSSAHASH=1110 should have matched for 'bar', '0'")
6969
}
70-
wantPrefix(t, msg, "bar.0 [bisect-match ")
71-
wantContains(t, msg, "\nGOSSAHASH triggered bar.0 ")
70+
wantPrefix(t, msg, "bar.0: note [bisect-match ")
71+
wantContains(t, msg, "\nGOSSAHASH triggered bar.0: note ")
7272
}
7373

7474
func TestYMatch(t *testing.T) {
7575
b := new(bytes.Buffer)
76-
hd := NewHashDebug("GOSSAHASH", "y", b)
77-
check := hd.MatchPkgFunc("bar", "0")
76+
hd := NewHashDebug("GOSSAHASH", "vy", b)
77+
check := hd.MatchPkgFunc("bar", "0", nil)
7878
msg := b.String()
7979
t.Logf("message was '%s'", msg)
8080
if !check {
@@ -86,8 +86,8 @@ func TestYMatch(t *testing.T) {
8686

8787
func TestNMatch(t *testing.T) {
8888
b := new(bytes.Buffer)
89-
hd := NewHashDebug("GOSSAHASH", "n", b)
90-
check := hd.MatchPkgFunc("bar", "0")
89+
hd := NewHashDebug("GOSSAHASH", "vn", b)
90+
check := hd.MatchPkgFunc("bar", "0", nil)
9191
msg := b.String()
9292
t.Logf("message was '%s'", msg)
9393
if check {
@@ -100,7 +100,7 @@ func TestNMatch(t *testing.T) {
100100
func TestHashNoMatch(t *testing.T) {
101101
b := new(bytes.Buffer)
102102
hd := NewHashDebug("GOSSAHASH", "01110", b)
103-
check := hd.MatchPkgFunc("bar", "0")
103+
check := hd.MatchPkgFunc("bar", "0", nil)
104104
msg := b.String()
105105
t.Logf("message was '%s'", msg)
106106
if check {
@@ -116,7 +116,7 @@ func TestHashSecondMatch(t *testing.T) {
116116
b := new(bytes.Buffer)
117117
hd := NewHashDebug("GOSSAHASH", "01110/11110", b)
118118

119-
check := hd.MatchPkgFunc("bar", "0")
119+
check := hd.MatchPkgFunc("bar", "0", nil)
120120
msg := b.String()
121121
t.Logf("message was '%s'", msg)
122122
if !check {

src/cmd/compile/internal/loopvar/loopvar.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func ForCapture(fn *ir.Func) []VarAndLoop {
9191
// subject to hash-variable debugging.
9292
maybeReplaceVar := func(k ir.Node, x *ir.RangeStmt) ir.Node {
9393
if n, ok := k.(*ir.Name); ok && possiblyLeaked[n] {
94-
if base.LoopVarHash.MatchPos(n.Pos()) {
94+
if base.LoopVarHash.MatchPos(n.Pos(), nil) {
9595
// Rename the loop key, prefix body with assignment from loop key
9696
transformed = append(transformed, VarAndLoop{n, x, lastPos})
9797
tk := typecheck.Temp(n.Type())
@@ -199,7 +199,7 @@ func ForCapture(fn *ir.Func) []VarAndLoop {
199199
forAllDefInInit(x, func(z ir.Node) {
200200
if n, ok := z.(*ir.Name); ok && possiblyLeaked[n] {
201201
// Hash on n.Pos() for most precise failure location.
202-
if base.LoopVarHash.MatchPos(n.Pos()) {
202+
if base.LoopVarHash.MatchPos(n.Pos(), nil) {
203203
leaked = append(leaked, n)
204204
}
205205
}

src/cmd/compile/internal/loopvar/loopvar_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func TestLoopVarHashes(t *testing.T) {
191191
return string(b)
192192
}
193193

194-
m := f("001100110110110010100100")
194+
m := f("v001100110110110010100100")
195195
t.Logf(m)
196196

197197
mCount := strings.Count(m, "loopvarhash triggered cmd/compile/internal/loopvar/testdata/inlines/main.go:27:6 001100110110110010100100")

src/cmd/compile/internal/ssa/func.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,5 +807,5 @@ func (f *Func) useFMA(v *Value) bool {
807807
if base.FmaHash == nil {
808808
return true
809809
}
810-
return base.FmaHash.MatchPos(v.Pos)
810+
return base.FmaHash.MatchPos(v.Pos, nil)
811811
}

0 commit comments

Comments
 (0)