Gilnaa / memoffset

offsetof for Rust
MIT License
224 stars 29 forks source link

offset_of! consumes too much stack space in dev build #49

Open jeehoonkang opened 3 years ago

jeehoonkang commented 3 years ago

offset_of! (and probably the other macros in this crate) consumes too much stack space in dev build, especially when the type is big. It's probably because it's declaring a (uninitialized) variable of the type. It's optimized out in the release build.

It affects my workflow in developing an OS in Rust. Its dev build won't boot because offset_of! of a big struct (2KiB) used up the limited amount of kernel stack (4KiB), incurring stack overflow.

RalfJung commented 3 years ago

Hm, that is unfortunate. But also I do not think there currently is a way to do offset_of! in Rust without allocating the relevant memory somewhere (and relying on the optimizer to remove it again). We have to avoid this UB:

Dereferencing (using the * operator on) a dangling or unaligned raw pointer.

If you are okay with using nightly Rust, an option might be to run offset_of! in a const -- then the stack space is used during CTFE and should not impact runtime code.

avl commented 1 year ago

Maybe we could create a single MaybeUninit::<[u128;N]> as a static variable somewhere, with some suitably large 'N', and use it for all offset_of-calculations, regardless of type? The argument is that a *const MaybeUninit::<[u128;128]> surely can be casted safely to a *const MaybeUninit::<(u32,u32)>, or whatever type the user tried to get the offset for? This would save stack space, but waste static object space.

Example code (which is accepted by Miri): https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4045ba8325b43f0ffd271f1f3119b13e

Only problem is that it'd be hard to determine how large this buffer needs to be. Might be an insurmountable problem.