uber-go / nilaway

Static analysis tool to detect potential nil panics in Go code
Apache License 2.0
3.07k stars 61 forks source link

nilaway panics - "internal error: encoding of *affiliation.AffliliationCache fact failed" #135

Open markvai opened 10 months ago

markvai commented 10 months ago
$ nilaway -debug fpstv ./...
14:25:35.972386 load [./...]
14:25:43.019609 building graph of analysis passes
/usr/local/go/src/runtime/internal/atomic/unaligned.go:7:6: object func atomic.panicUnaligned() has fact noReturn
/usr/local/go/src/runtime/cgocallback.go:11:6: object func runtime._cgo_panic_internal(p *byte) has fact noReturn
/usr/local/go/src/runtime/cpuprof.go:208:6: object func runtime.CPUProfile() []byte has fact noReturn
/usr/local/go/src/runtime/error.go:305:6: object func runtime.panicwrap() has fact noReturn
/usr/local/go/src/runtime/iface.go:262:6: object func runtime.panicdottypeE(have *abi.Type, want *abi.Type, iface *abi.Type) has fact noReturn
/usr/local/go/src/runtime/iface.go:268:6: object func runtime.panicdottypeI(have *runtime.itab, want *abi.Type, iface *abi.Type) has fact noReturn
/usr/local/go/src/runtime/iface.go:278:6: object func runtime.panicnildottype(want *abi.Type) has fact noReturn
/usr/local/go/src/runtime/mfinal.go:176:6: object func runtime.runfinq() has fact noReturn
/usr/local/go/src/runtime/mgc.go:1259:6: object func runtime.gcBgMarkWorker() has fact noReturn
/usr/local/go/src/runtime/mgcscavenge.go:649:6: object func runtime.bgscavenge(c chan int) has fact noReturn
/usr/local/go/src/runtime/mgcsweep.go:273:6: object func runtime.bgsweep(c chan int) has fact noReturn
/usr/local/go/src/runtime/panic.go:112:6: object func runtime.goPanicIndex(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:118:6: object func runtime.goPanicIndexU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:126:6: object func runtime.goPanicSliceAlen(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:132:6: object func runtime.goPanicSliceAlenU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:138:6: object func runtime.goPanicSliceAcap(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:144:6: object func runtime.goPanicSliceAcapU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:152:6: object func runtime.goPanicSliceB(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:158:6: object func runtime.goPanicSliceBU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:164:6: object func runtime.goPanicSlice3Alen(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:168:6: object func runtime.goPanicSlice3AlenU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:172:6: object func runtime.goPanicSlice3Acap(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:176:6: object func runtime.goPanicSlice3AcapU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:182:6: object func runtime.goPanicSlice3B(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:186:6: object func runtime.goPanicSlice3BU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:192:6: object func runtime.goPanicSlice3C(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:196:6: object func runtime.goPanicSlice3CU(x uint, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:202:6: object func runtime.goPanicSliceConvert(x int, y int) has fact noReturn
/usr/local/go/src/runtime/panic.go:230:6: object func runtime.panicshift() has fact noReturn
/usr/local/go/src/runtime/panic.go:238:6: object func runtime.panicdivide() has fact noReturn
/usr/local/go/src/runtime/panic.go:245:6: object func runtime.panicoverflow() has fact noReturn
/usr/local/go/src/runtime/panic.go:252:6: object func runtime.panicfloat() has fact noReturn
/usr/local/go/src/runtime/panic.go:259:6: object func runtime.panicmem() has fact noReturn
/usr/local/go/src/runtime/panic.go:264:6: object func runtime.panicmemAddr(addr uintptr) has fact noReturn
/usr/local/go/src/runtime/panic.go:489:6: object func runtime.Goexit() has fact noReturn
/usr/local/go/src/runtime/proc.go:313:6: object func runtime.forcegchelper() has fact noReturn
/usr/local/go/src/runtime/proc.go:510:6: object func runtime.badreflectcall() has fact noReturn
/usr/local/go/src/runtime/proc.go:2491:6: object func runtime.templateThread() has fact noReturn
/usr/local/go/src/runtime/proc.go:5515:6: object func runtime.sysmon() has fact noReturn
/usr/local/go/src/runtime/signal_unix.go:842:6: object func runtime.sigpanic() has fact noReturn
/usr/local/go/src/runtime/slice.go:28:6: object func runtime.panicmakeslicelen() has fact noReturn
/usr/local/go/src/runtime/slice.go:32:6: object func runtime.panicmakeslicecap() has fact noReturn
/usr/local/go/src/runtime/unsafe.go:44:6: object func runtime.panicunsafestringlen() has fact noReturn
/usr/local/go/src/runtime/unsafe.go:48:6: object func runtime.panicunsafestringnilptr() has fact noReturn
/usr/local/go/src/runtime/unsafe.go:99:6: object func runtime.panicunsafeslicelen1(pc uintptr) has fact noReturn
/usr/local/go/src/runtime/unsafe.go:111:6: object func runtime.panicunsafeslicenilptr1(pc uintptr) has fact noReturn
/usr/local/go/src/runtime/unsafe.go:92:6: object func runtime.panicunsafeslicelen() has fact noReturn
/usr/local/go/src/runtime/unsafe.go:104:6: object func runtime.panicunsafeslicenilptr() has fact noReturn
/usr/local/go/src/syscall/syscall.go:102:6: object func syscall.Exit(code int) has fact noReturn
/usr/local/go/src/syscall/time_nofake.go:11:6: object func syscall.faketimeWrite(fd int, p []byte) int has fact noReturn
/usr/local/go/src/runtime/alg.go:5:1: package runtime has fact &{map[{internal/abi.RegArgs }:%!s(bool=true) {runtime.PanicNilError }:%!s(bool=true) {runtime.errorString error}:%!s(bool=true) {runtime.g }:%!s(bool=true) {runtime.m }:%!s(bool=true) {runtime.pinner }:%!s(bool=true) {runtime.pollDesc }:%!s(bool=true) {runtime.scavengerState }:%!s(bool=true) {runtime.userArena }:%!s(bool=true)]}
14:25:43.082688 internal error: encoding of *affiliation.AffliliationCache fact failed in nilaway_affiliation_analyzer@internal/reflectlite
panic: internal error: encoding of *affiliation.AffliliationCache fact failed in nilaway_affiliation_analyzer@internal/reflectlite

goroutine 1 [running]:
log.Panicf({0x81e7d5?, 0xc0d057d088?}, {0xc03025c0e0?, 0x2?, 0x414c28?})
        /usr/local/go/src/log/log.go:439 +0x65
golang.org/x/tools/go/analysis/internal/checker.inheritFacts(0xc0fadb0820, 0xc0fadb0e60)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:835 +0x3c8
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0fadb0820)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:736 +0x465
sync.(*Once).doSlow(0xc03025c510?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc0be541a50, 0x2, 0xc0d2edc874?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0fadb06e0)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc03025c888?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc064350a00, 0x6, 0xc0cef3c0c0?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0fadb05a0)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc03025cc00?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc0be541af0, 0x2, 0xab7e00?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0fadb0500)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc03025cf78?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc0c743a900, 0x4, 0x0?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0f8925720)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc1324ff2f0?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc0c743a920, 0x4, 0xab7874?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0f8925680)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc1324ff668?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc0bcc1c4b0, 0x2, 0xab7700?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc0f8925540)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:687 +0x48
sync.(*Once).doSlow(0xc1324ff9e0?, 0x40d1e5?)
        /usr/local/go/src/sync/once.go:74 +0xbf
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/analysis/internal/checker.(*action).exec(...)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:683
golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0x7ffef9d3006c?)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:671 +0x45
golang.org/x/tools/go/analysis/internal/checker.execAll({0xc04cddc000, 0xab, 0x71c176?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:675 +0x102
golang.org/x/tools/go/analysis/internal/checker.analyze({0xc01b9e6b00, 0xab, 0x1?}, {0xc000114c68, 0x1, 0xc000197da0?})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:311 +0x1f8
golang.org/x/tools/go/analysis/internal/checker.Run({0xc000122070, 0x1, 0x1}, {0xc000114c68?, 0x1, 0x1})
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:147 +0x830
golang.org/x/tools/go/analysis/singlechecker.Main(0xab7400)
        /home/mark/go/pkg/mod/golang.org/x/tools@v0.11.0/go/analysis/singlechecker/singlechecker.go:75 +0x265
main.main()
        /home/mark/go/pkg/mod/go.uber.org/nilaway@v0.0.0-20231117175943-a267567c6fff/cmd/nilaway/main.go:140 +0x165

$ go version
go version go1.21.0 linux/amd64
markvai commented 10 months ago

The error that triggers the panic is from golang.org/x/tools@v0.11.0/go/analysis/internal/checker/checker.go:865, when checking for determinstic encoding.

if !bytes.Equal(buf.Bytes(), buf2.Bytes()) {
return nil, fmt.Errorf("encoding of %T fact is nondeterministic", fact)
}

Upgrading x/tools to v0.15.0 didn't change the result.