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: "goroutine stack exceeds 250000000-byte limit" on linux-arm #35470

Open
bcmills opened this issue Nov 8, 2019 · 7 comments
Assignees
Milestone

Comments

@bcmills
Copy link
Member

@bcmills bcmills commented Nov 8, 2019

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Nov 9, 2019

These stacks are not large at all, so the problem is not actual stack overflow, but a false report of stack overflow.

@cherrymui

This comment has been minimized.

Copy link
Contributor

@cherrymui cherrymui commented Nov 9, 2019

I can imagine a possibility: if there are both a synchronous preemption request (by clobbering the stack guard) and an asynchronous one (by signal), and the goroutine in a function prologue first sees the clobbered stack guard, so it will call morestack. If the signal lands after the CMP instruction but before the call to morestack, it will be asynchronously preempted, enter the scheduler. When it is resumed, the scheduler clears the preemption request, unclobbers the stack guard. But the resumed goroutine will still call morestack (as it has passed the CMP instruction). morestack will, as there is no preemption request, double the stack unnecessarily. If this happens multiple times, the stack may grow too big, although only a small amount is actually used.

I let it print the current stack bounds in the stack-too-large error message, and the stack is indeed quite large, with only a small amount used:

runtime: goroutine stack exceeds 250000000-byte limit
	sp=0x1847dad8 stack=[0x10480000, 0x18480000]
fatal error: stack overflow

In theory this can happen on other platforms. Not sure why this is only seen on the ARM builder.

@cherrymui

This comment has been minimized.

Copy link
Contributor

@cherrymui cherrymui commented Nov 9, 2019

Maybe we want to disable async preemption in function prologue between the CMP instruction and the call to morestack? As it will call morestack, it will be preempted anyway.

@randall77

This comment has been minimized.

Copy link
Contributor

@randall77 randall77 commented Nov 9, 2019

@cherrymui That sounds like a good idea.

I think we might have to start at the load of the stack guard, as the CMP result is predestined at that point. But then maybe we need to only prevent async preemption if that loaded value is in fact the preempted guard.

Tricky.

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Nov 15, 2019

Change https://golang.org/cl/207350 mentions this issue: cmd/internal/obj: mark split-stack prologue nonpreemptible

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Nov 15, 2019

Change https://golang.org/cl/207351 mentions this issue: runtime: print more information on stack overflow

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Nov 15, 2019

Change https://golang.org/cl/207349 mentions this issue: cmd/internal/obj, runtime: use register map to mark unsafe points

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.