Skip to content
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

runtime: add "maymorestack" hook for testing stack growth prologues #48297

Open
aclements opened this issue Sep 9, 2021 · 5 comments
Open

runtime: add "maymorestack" hook for testing stack growth prologues #48297

aclements opened this issue Sep 9, 2021 · 5 comments
Assignees
Milestone

Comments

@aclements
Copy link
Member

@aclements aclements commented Sep 9, 2021

I plan to add a debugging hook for internal use that will be invoked in the prologue of any function that may call morestack (the stack growth function). This is inspired by the preemption bugs that led to #47302, #47304, and #47441.

In general, testing around morestack is difficult because almost all Go functions can potentially call morestack, but very few do at run time, and which ones do are highly unpredictable. As a result, if a particular function is incorrectly sensitive to whether morestack gets invoked (either to grow the stack or to preempt), it's highly unlikely that general testing will actually trigger the morestack path in that function.

The hook function will be called unconditionally before the stack bound check in any function that could call morestack. This particular placement means the hook can inject preemption or stack growth by simply setting the stack bound to a poisoned value and returning, since the stack bound check will then fail and enter morestack.

This hook is also useful for more precise lock order checking because it lets us model functions that "may" acquire any of the locks acquired by morestack. These are lock edges we only see in the rare cases where morestack is actually called, but lie latent in any function that could call it.

@aclements aclements added this to the Unplanned milestone Sep 9, 2021
@aclements aclements self-assigned this Sep 9, 2021
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 9, 2021

The hook function will be called unconditionally before the stack bound check in any function that could call morestack.

How do you plan to make this happen? Presumably we don't want to always call the hook in every function. Perhaps I misunderstand.

@aclements
Copy link
Member Author

@aclements aclements commented Sep 9, 2021

I plan to always call the hook in every function. The hook call will only be added if the debug option is supplied, so the performance isn't really an issue. And, in fact, I've already implemented this and it has shockingly little performance impact. Unless you were thinking of some other problem?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 9, 2021

How is the debug option supplied?

@aclements
Copy link
Member Author

@aclements aclements commented Sep 9, 2021

In my current prototype, the compiler takes it as a -d=maymorestack= argument and the assembler takes it as -maymorestack= (because it doesn't have an equivalent of -d). So, e.g., you can supply the preemption-testing hook as

GOFLAGS="-gcflags=runtime=-d=maymorestack=runtime.mayMoreStackPreempt -asmflags=runtime=-maymorestack=runtime.mayMoreStackPreempt"

But I'm happy to change this.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 9, 2021

That seems fine. Thanks. I just didn't find the original description very clear. We have various different kinds of debugging hooks (e.g., GODEBUG).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants