Figuring out stack sizes for functions and values

I'm looking for tips on how to figure out some related things:

  • Why is a certain function allocating an unreasonable amount of stack space? E.g. where do these 10984 bytes come from:
   0x00005555557163b3 <+3>:	mov    $0x2ae8,%eax
=> 0x00005555557163b8 <+8>:	call   0x555555f8e6b9 <__rust_probestack>
   0x00005555557163bd <+13>:	sub    %rax,%rsp
  • Can the compiler print the sizes of types as it goes? Clippy warned me about an enum with a big variant, and it was indeed useful, but it would be nice to be able to find other footguns early.

By hand, I printed the sizes of all the local variables and the result types in my function above, but they only use 788 bytes. So I wonder what I am missing.

The nightly toolchain has an option to print type sizes to the console during compilation. You can enable just for your crate like this:

cargo +nightly rustc -- -Z print-type-sizes

Or for all crates in the dependency graph, like this:

RUSTFLAGS="-Z print-type-sizes" cargo +nightly check

There is also a -Z emit-stack-sizes option, but I don't know how/where to read the data that it emits. (I think it is written to a section of the compiled binary.)

This is great, thank you! I'm having trouble with emit-stack-sizes, but hopefully I just have to dig into what the linker is doing. japaric has a cargo-stack-sizes tool to use that, too.