Code change:
use crate::io; use crate::mem; <del> use crate::sync; </del> <ins> use crate::ptr; </ins> use crate::sys::c; <del> /// The kinds of HashMap RNG that may be available #[derive(Clone, Copy, Debug, PartialEq)] enum HashMapRng { Preferred, Fallback, } </del> pub fn hashmap_random_keys() -> (u64, u64) { <del> match get_hashmap_rng() { HashMapRng::Preferred => { preferred_rng().expect("couldn't generate random bytes with preferred RNG") } HashMapRng::Fallback => { fallback_rng().expect("couldn't generate random bytes with fallback RNG") } } } /// Returns the HashMap RNG that should be used /// /// Panics if they are both broken fn get_hashmap_rng() -> HashMapRng { // Assume that if the preferred RNG is broken the first time we use it, it likely means // that: the DLL has failed to load, there is no point to calling it over-and-over again, // and we should cache the result static VALUE: sync::OnceLock<HashMapRng> = sync::OnceLock::new(); *VALUE.get_or_init(choose_hashmap_rng) } /// Test whether we should use the preferred or fallback RNG /// /// If the preferred RNG is successful, we choose it. Otherwise, if the fallback RNG is successful, /// we choose that /// /// Panics if both the preferred and the fallback RNG are both non-functional fn choose_hashmap_rng() -> HashMapRng { let preferred_error = match preferred_rng() { Ok(_) => return HashMapRng::Preferred, Err(e) => e, }; match fallback_rng() { Ok(_) => return HashMapRng::Fallback, Err(fallback_error) => panic!( "preferred RNG broken: `{}`, fallback RNG broken: `{}`", preferred_error, fallback_error ), } } /// Generate random numbers using the preferred RNG function (BCryptGenRandom) fn preferred_rng() -> Result<(u64, u64), io::Error> { use crate::ptr; </del> let mut v = (0, 0); let ret = unsafe { c::BCryptGenRandom(

Related discussion:
text: To be clear, we (at least at the moment) don't really support calling into libstd from initialization contexts like DllMain. We sometimes fix bugs from this it, but mostly on a best-effort basis, which depending on stuff like severity/impact/maintance burden/hackiness/the weather/etc, all of which is mostly judged on an ad-hoc basis. Even when we fix it, there's no guarantee it'd going to keep working in the future. Given that it's only broken on Win7[^1] and there doesn't seem to be a great approach that wouldn't make things worse outside of it (and/or for on newer windows), I'm inclined to just say... sorry, it's not really supported. Anyway, while things from libstd like HashMap (well, the it uses in particular) is unlikely to be viable in DllMain (at least on win7), I think things from liballoc should be fine (so long as your allocator supports it), so my recommendation might be to switch to using /, which shouldn't have this issue. Another option would be to use a different hasher that doesn't need randomness, but be careful about that. [^1]: It may be worth reconsidering if this happens on newer Windows as well. There are some... unpleasant approaches we could consider, but I don't think they're worth it for Win7 given how close to EOL it is, and the fact that we don't really support use from DllMain anyway.
I am loading an dll from DLL main for years now, and you just told me that Microsoft can screw me over at any time Well thanks for warning. I will keep doing that and hope Microsoft will never change that.
If you scroll down this page it has a list of things Microsoft says you should never do in DllMain:
This is what I was saying before about the stack trace not actually reflecting the changes -- but I also mentioned the bizarre coincidence that this hang bisects to exactly the same nightly as the one with the patch. I agree with keeping the revised changes in all cases and libstd support being a best-effort deal, but I'm guessing that something in how/what gets locked/attempted before the call into changes the state in some unsupported way that caused the bug to surface. I'd be curious what Application Verifier finds if you run it against a minimum repro.