Stack check musings


#1

Hello,

Background: I’m using Rust for a cross-platform mobile library that is used within an Objective-C iOS application and a Java Android application (using a JNI shim also in Rust). I’ve a self-built Rust toolchain that targets seven mobile triples. The Rust code is complex enough to warrant the use of multiple crates and Cargo. So far, this approach is working well :smile:

The Rust code doesn’t create the threads of execution in my app, and as a result, the stack check prologues are occasionally misfiring on Android (they’re disabled by default for iOS targets). To fix this, I’ve built a new Rust toolchain with morestack set to false within src/librustc_back/target/android_base.rs. The reason for rolling this into the rust compiler rather than relying on the no-stack-check rust compiler flag is the difficultly in passing this option to every Cargo dependency. Plus, I really need a no-stack-check libstd.

I’m aware that I’m losing out on safety by disabling the stack checks on Android, but since iOS doesn’t have them anyway, I figure I’m not really losing that much. Additionally, it isn’t obvious how I’d solve the problem of an external thread invoking my Rust function. Even if the entry points of my library were marked with #[no_stack_check], I’d be severely limited in what libstd functions I could use. Even if I was careful to only use functions also marked as #[no_stack_check], the compiler wouldn’t help enforce this in the face of libstd or my own code changing.

So, to my questions, most of which assume that Rust wishes to easily support the use-case of hosting a no-stack-check Rust library within another environment:

  1. Does my morestack hack described above, where I modify the compiler for Android targets, seem like a sensible approach to solving the issue?

  2. Does any user documentation exist that explains the potentially problematic stack check prologues in the case of external threads invoking Rust functions?

  3. Is there value in Cargo offering a way of passing Rust compiler flags to all dependencies of a crate (in this case, passing -C no-stack-check)?

  4. Is there value in a Rust configure option that disables stack checks for a given target triple (akin to my morestack hack described above)?

  5. It seems that stack-check / no-stack-check is an axis perpendicular to that of the target triple axis, forming a variant of a triple. Anyone have any thoughts on this?

  6. Given that the stack check prologues are not universally supported across all targets, what does the future hold for stack checking?

  7. Is there, or is there value in adding, a compilation/linker lint for ensuring that a chain of function calls are all marked as #[no_stack_check]?

For (2), I blew a bunch of time debugging the crazy non-existent stack overflows, so I’m prepared to write a paragraph or two about this topic somewhere appropriate to save others the same pain.

Kind regards,

Mark


#2

It’s sensible enough, though you could potentially use a flexible target spec instead to avoid having to build your own rustc.

[quote=“mark_buer, post:1, topic:2779”] Is there value in Cargo offering a way of passing Rust compiler flags to all dependencies of a crate (in this case, passing -C no-stack-check)?[/quote] An ugly way is to create a wrapper script that just does rustc -C flags etc "$@" and point cargo to it by usinig the RUSTC environment variable.

morestack has been removed recently, it’s been fairly useless for a while now. Try using nightly or beta instead of stable rustsc.


#3

@arcnmx Thanks for the info, I’ll switch to nightly :slight_smile:

Rust moves too fast to keep up with!