-
Notifications
You must be signed in to change notification settings - Fork 84
Disable default-features on rand dependency to avoid std version #107
Conversation
LGTM. Could you add an example that links to rand with default features disabled? That should serve as a regression test. |
note that to get the example to build on CI you'll have to add it: Lines 14 to 28 in 5baa082
|
Shouldn't any of the existing examples do? The rand stuff is used for generation of unique linker symbols, no? |
@japaric Please have a look now. |
Hmm, the build is failing since the first commit with: "error[E0658]: use of unstable library feature 'rustc_private'", and I don't understand why ... |
😀. And now travis-ci is running into the exact same problem I mentioned in the ticket before... |
I think it's because the version seems to be newer than the upstream version so it uses that instead which triggers this problem. As I said: I'm having the same troubles locally. |
macros/Cargo.toml
Outdated
proc-macro2 = "0.4.15" | ||
|
||
[dependencies.syn] | ||
features = ["extra-traits", "full"] | ||
version = "0.14.8" | ||
|
||
[depedencies.rand] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh lol. I see the problem. This is a typo; the "n" is missing after "depe".
The typo solves the weird "rustc_private" issue, but this still doesn't work because @therealprof how did you get this working locally? |
I simply compiled the example via |
LOL and of course once I fixed the type it does not compile anymore. 😀 Raining lemons today... |
@therealprof you didn't add |
That's indeed what I did. Do you want me to rewrite the rand stuff in macros to use the seedable rng which works in no_std? |
Yes, please. Though, I'm concerned that using a seed which is not randomly generated will result in (a) predictable identifiers which then the user can the use to call exception handlers breaking the non-reentrant invariant, and / or (b) collisions between |
@japaric Well, the stuff is not really cryptographic anyway. If someone wants to desperately do bad stuff with the entry points, they can still do it. Collisions would be indeed a problem but a |
They can't with the current implementation. If they call
That could turn into UB in any future LLVM release so it's not an option. |
Can we just prevent the function from being called from safe code? I get that we can't just hide it in a private module (sadly, as that seems like it would totally fix the issue) but perhaps we can stick it inside an unsafe function wrapper with a predictable name? Or any other options to avoid rand? Otherwise... seed with the build time... 😈 |
Sure... but then again if someone really wants to do it they can do still it after the fact, i.e. without recompiling from source.
Well, it's a new feature anyway. 😏
Uhm....
Or address of something in the running process. ;) |
That's an option but we would need a trampoline to preserve the safety that the user declared: #[exception]
fn SysTick() { .. }
// expands into
#[no_mangle]
pub unsafe fn SysTic() {
// copy paste the user function here
#[inline(always)]
fn SysTick() { .. }
SysTick()
}
Seed with |
You should read through the Unsafe Code Guidelines team discussions. Apparently most |
I'm aware of |
475cbba
to
5f62fd8
Compare
Due to the single dependency tree, the attempted use of a std version flips all depending crates to the std version as well which will not compile on no_std systems. Fixes rust-embedded#105 Signed-off-by: Daniel Egger <daniel@eggers-club.de>
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
5f62fd8
to
b300508
Compare
... and of course the Rng is seeded on each invocation of the random token function while the seed is only increasing each second which one fast machines means: crap (and I've been able to experience it first hand). I've added an atomic counter, increased on each invocation (much easier than the pro way of initialising once and reusing the same Rng), to continuously change the seed. Now collisions are a thing of the past. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. r=me with nits addressed.
macros/src/lib.rs
Outdated
|
||
use core::mem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why core::mem
and not std::mem
?
macros/src/lib.rs
Outdated
@@ -492,7 +499,10 @@ pub fn pre_init(args: TokenStream, input: TokenStream) -> TokenStream { | |||
|
|||
// Creates a random identifier | |||
fn random_ident() -> Ident { | |||
let mut rng = rand::thread_rng(); | |||
let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); | |||
CALL_COUNT.fetch_add(1, Ordering::SeqCst); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns the previous value. Why not use that instead of doing another atomic load?
macros/src/lib.rs
Outdated
let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); | ||
CALL_COUNT.fetch_add(1, Ordering::SeqCst); | ||
let seed = [seed, CALL_COUNT.load(Ordering::SeqCst) as u64]; | ||
let mut rng = rand::rngs::SmallRng::from_seed( unsafe { mem::transmute(seed) } ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use unsafe
code here. There are methods to go from u64
to [u8; 8]
and vice versa that could be used here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To the best of my knowledge only in nightly...
https://doc.rust-lang.org/nightly/std/primitive.u64.html#method.to_be_bytes
Of course I could do some bitmasking. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To the best of my knowledge only in nightly...
Still? I thought it was already stabilized. Perhaps I was thinking of f32.to_bits
.
Of course I could do some bitmasking. ;)
I would prefer that over unsafe code.
Could we use |
Where did you dig that out? 😲 |
I was more thinking you could seed it once with that and then not worry about the counter. Though I guess you have to do the same twiddling to turn it into |
The RNG is seeded from the current time and an counter increasing with each call to yield different random values on each invocation. Signed-off-by: Daniel Egger <daniel@eggers-club.de>
b300508
to
ca4e52b
Compare
So... bit twiddling it is. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
bors r+
107: Disable default-features on rand dependency to avoid std version r=japaric a=therealprof Due to the single dependency tree, the attempted use of a std version flips all depending crates to the std version as well which will not compile on no_std systems. Fixes #105 Signed-off-by: Daniel Egger <daniel@eggers-club.de> Co-authored-by: Daniel Egger <daniel@eggers-club.de>
Build succeeded |
Great work! |
Due to the single dependency tree, the attempted use of a std version
flips all depending crates to the std version as well which will not
compile on no_std systems.
Fixes #105
Signed-off-by: Daniel Egger daniel@eggers-club.de