-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/vet: improve the frame pointer check #69838
Comments
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
I don't understand, for example, this one: https://go-mod-viewer.appspot.com/github.com/klauspost/[email protected]/galois_gen_amd64.s#L11535 It is in a function with a nonzero frame size, so we already spill/restore BP. The vet check shouldn't be checking such functions. |
@prattmic and I discussed this on Gopher slack, small mistake in the change to the analyzer. If the branch check (which also checks for RET) is dropped with no other changes, then the analyzer stays "active" once it sees a frameless function for the first time. So in that example, it's looking for BP writes because the preceding function was frameless. We can tweak it to reset the active flag for every TEXT line. |
Excluding the false positives for functions with frames, the rest seem to mostly be true positives. One exception is https://go-mod-viewer.appspot.com/github.com/nicocha30/[email protected]/pkg/ring0/entry_amd64.s#L467, which saves the frame pointer in a macro. Unless the vet check does preprocessing it's going to miss things like that. |
Change https://go.dev/cl/635338 mentions this issue: |
Change https://go.dev/cl/640075 mentions this issue: |
The
framepointer
check fromgo vet
is currently quite conservative. Since Go 1.21, frame pointers have become more load-bearing in the Go runtime. They're now used on amd64 and arm64 to collect call stacks for the execution tracer and the block & mutex profilers. Now, frame pointer bugs can crash Go programs, whereas before they would merely result in broken call stacks for external profilers like Linuxperf
.For example, #69629 was ultimately caused by a bug in programatically-generated amd64 assembly which clobbered the frame pointer register. As of Go 1.23.2,
go vet
misses that frame pointer bug. This is because the frame pointer is clobbered after a branch instruction, and the check aborts if it reaches a branch.I think we should try to expand the number of bugs the
framepointer
check can catch. For example, arm64 support would be good. We also might be able to drop that branch check, or flag assembly that writes torbp
without apush rbp
near the beginning and apop rbp
before returning. These kinds of ideas should of course be tested against existing open source Go assembly code, since I assume there is little (if any?) tolerance for false positives ingo vet
tools.The text was updated successfully, but these errors were encountered: