Bad parsing and/or generation of instrumented code
armfazh opened this issue · 3 comments
Issue: The code of the function times3
produced by instrumentation is wrong.
This is the minimal reproducible example.
File: fuzz.go
package fuzz
func timesN(b []byte, n int) { b[0] *= byte(n) }
func times3(b []byte) { timesN(b, 3) }
//go:noescape
func times5(b []byte)
func Fuzz(data []byte) int {
times3(data)
times5(data)
return 0
}
File: times.s
#include "textflag.h"
TEXT ·times5(SB), NOSPLIT,$0
RET
Command
$ go-fuzz-build
Output:
$ go-fuzz-build
fuzz.go:4: can only use //go:noescape with external func implementations
Instrumented code (wrong)
//line /home/user/bug/fuzz.go:1
package fuzz
//line /home/user/bug/fuzz.go:1
import _go_fuzz_dep_ "go-fuzz-dep"
func timesN(b []byte, n int) { _go_fuzz_dep_.CoverTab[22588]++; b[0] *= byte(n) }
func times3(b []byte) { _go_fuzz_dep_.CoverTab[
//go:noescape
//line /home/user/bug/fuzz.go:4
44810]++; timesN(b, 3) }
//line /home/user/bug/fuzz.go:7
func times5(b []byte)
//line /home/user/bug/fuzz.go:10
func Fuzz(data []byte) int {
//line /home/user/bug/fuzz.go:10
_go_fuzz_dep_.CoverTab[5262]++
times3(data)
times5(data)
return 0
}
//line /home/user/bug/fuzz.go:15
var _ = _go_fuzz_dep_.CoverTab
Instrumented code (expected/correct)
//line /home/user/bug/fuzz.go:1
package fuzz
//line /home/user/bug/fuzz.go:1
import _go_fuzz_dep_ "go-fuzz-dep"
func timesN(b []byte, n int) { _go_fuzz_dep_.CoverTab[22588]++; b[0] *= byte(n) }
func times3(b []byte) { _go_fuzz_dep_.CoverTab[44810]++;
//line /home/user/bug/fuzz.go:4
timesN(b, 3)
}
//line /home/user/bug/fuzz.go:7
//go:noescape
func times5(b []byte)
//line /home/user/bug/fuzz.go:10
func Fuzz(data []byte) int {
//line /home/user/bug/fuzz.go:10
_go_fuzz_dep_.CoverTab[5262]++
times3(data)
times5(data)
return 0
}
//line /home/user/bug/fuzz.go:15
var _ = _go_fuzz_dep_.CoverTab
One quick workaround is to define times3
as:
func times3(b []byte) {
timesN(b, 3)
}
The build completes successfully, but the parsing bug is still there.
Wonder if it's go/ast bug and affects go tool cover too.
Seems like a corner case go/ast or go/printer bug. Our could have to do with exactly how we insert the coverage statement. Needs investigation.
This doesn't affect go tool cover, since it doesn't use go/ast or go/printer any more. It uses plain text editing (internal package edit
). I'd really like to use that for go-fuzz, but we lose handy //line printing. I've described the difficulties here at length somewhere in a go-fuzz issue, don't recall where now.