Skip to content

builder: increase stack size margin for automatic stack allocation#5381

Merged
deadprogram merged 1 commit into
tinygo-org:devfrom
helvionics:de_automatic-stack-size-margin
Jun 8, 2026
Merged

builder: increase stack size margin for automatic stack allocation#5381
deadprogram merged 1 commit into
tinygo-org:devfrom
helvionics:de_automatic-stack-size-margin

Conversation

@digitalentity

@digitalentity digitalentity commented May 10, 2026

Copy link
Copy Markdown
Contributor

When TinyGo calculates stack sizes automatically, it performs a static analysis of the call graph. While this analysis correctly identifies the stack requirements for Go functions, it cannot account for stack usage within assembly-level routines that are not visible to the high-level analysis.

Specifically, tinygo_swapTask pushes callee-saved registers onto the current goroutine's stack during every context switch. If this overhead is not accounted for, a goroutine might overflow its stack during a context switch even if its Go-level stack usage is within limits.

With this change in determineStackSizes, we now look up the tinygo_swapTask function in the symbol table to determine its frame size. This context switch overhead is now added to the calculated stack size for all goroutines that have a bounded stack size.

Fixes #5375

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves TinyGo’s automatic goroutine stack size calculation by adding a safety margin for context switches, accounting for stack usage in tinygo_swapTask that is not visible to Go-level call graph analysis.

Changes:

  • Look up tinygo_swapTask in the computed call graph/symbol map and capture its frame size as context-switch overhead.
  • Add the context-switch overhead to all goroutine stack sizes that are compile-time Bounded.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread builder/build.go

@eliasnaur eliasnaur left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add "Fixes #5375"

Otherwise, @aykevl or @dgryski should probably take a look.

@aykevl aykevl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the wrong fix. The stack size of the goroutine swap functions should be taken care of already, since the assembly lists it as part of the CFA:

.cfi_def_cfa_offset 9*4

If it isn't taken into account, that's a different bug.

@digitalentity

Copy link
Copy Markdown
Contributor Author

@aykevl the bug is not that the .cfi_def_cfa_offset is not defined, the bug is that tinygo_swapTask is not accounted for by the stack size calculation because it's simply not part of the call tree of the goroutine. This fix is to account for it explicitly.

@digitalentity

Copy link
Copy Markdown
Contributor Author

In #5375 (comment) I've figured out that the crashes are actually happening because of the memory corruption which sometimes gets caught by the canary, but sometimes is silent.

With the increase of the autodetected stack size by 36 bytes (tinygo_swapTask frame size) as the only change the crashes were fixed - the code that was previously crashing after 5-15 minutes was tested to run for over 12h, so clearly the autodetected stack size was incorrect.

@aykevl

aykevl commented May 11, 2026

Copy link
Copy Markdown
Member

Ah sorry, I misread the PR. Will take another look later!

@digitalentity

Copy link
Copy Markdown
Contributor Author

@aykevl a gentle ping 😸

@digitalentity digitalentity requested a review from aykevl May 24, 2026 09:53
Adjust the stack size margin to account for the tinygo_swapTask overhead.
@digitalentity digitalentity force-pushed the de_automatic-stack-size-margin branch from 6c3fdd2 to 05955e5 Compare June 8, 2026 18:56
@digitalentity

Copy link
Copy Markdown
Contributor Author

@aykevl @eliasnaur @deadprogram can we merge this? it has been battle-tested on a very goroutine-heavy project which reliably crashed without this fix.

@deadprogram

Copy link
Copy Markdown
Member

I looked at this PR and it seems like it does correct the problem it says it does, without any bad side effects. Now merging, thank you @digitalentity and to @eliasnaur @aykevl and @dgryski for reviewing.

@deadprogram deadprogram merged commit 5fabc20 into tinygo-org:dev Jun 8, 2026
20 checks passed
@digitalentity digitalentity deleted the de_automatic-stack-size-margin branch June 9, 2026 06:25
@digitalentity

Copy link
Copy Markdown
Contributor Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Random crashes caused by incorrect goroutine stack size detection

5 participants