Skip to content

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

Open
digitalentity wants to merge 1 commit intotinygo-org:devfrom
helvionics:de_automatic-stack-size-margin
Open

builder: increase stack size margin for automatic stack allocation#5381
digitalentity wants to merge 1 commit intotinygo-org:devfrom
helvionics:de_automatic-stack-size-margin

Conversation

@digitalentity
Copy link
Copy Markdown

@digitalentity digitalentity commented May 10, 2026

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

Adjust the stack size margin to account for the tinygo_swapTask overhead.
Copy link
Copy Markdown

Copilot AI left a comment

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
// on every context switch. The static analysis correctly traces Go calls,
// but it cannot see into the assembly-level register push.
var contextSwitchOverhead uint64
if swapFuncs, ok := functions["tinygo_swapTask"]; ok && len(swapFuncs) == 1 {
Copy link
Copy Markdown
Contributor

@eliasnaur eliasnaur left a comment

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.

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

3 participants