Code change:
c::BCRYPT_USE_SYSTEM_PREFERRED_RNG, ) }; <del> if ret == 0 { Ok(v) } else { Err(io::Error::last_os_error()) } </del> <ins> if ret != 0 { fallback_rng() } else { v } </ins> } /// Generate random numbers using the fallback RNG function (RtlGenRandom) #[cfg(not(target_vendor = "uwp"))] <del> fn fallback_rng() -> Result<(u64, u64), io::Error> { </del> <ins> #[inline(never)] fn fallback_rng() -> (u64, u64) { </ins> let mut v = (0, 0); let ret = unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) }; <del> if ret != 0 { Ok(v) } else { Err(io::Error::last_os_error()) } </del> <ins> if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) } </ins> } /// We can't use RtlGenRandom with UWP, so there is no fallback #[cfg(target_vendor = "uwp")] <del> fn fallback_rng() -> Result<(u64, u64), io::Error> { Err(io::const_io_error!(io::ErrorKind::Unsupported, "RtlGenRandom() not supported on UWP")) </del> <ins> #[inline(never)] fn fallback_rng() -> (u64, u64) { panic!("fallback RNG broken: RtlGenRandom() not supported on UWP"); </ins> }

Related discussion:
text: It have something to do with initializing the logs in , but I have no clue what specific small detail it is that breaks it <details<summaryExe code (not much interesting)</summary<p</p</details<details<summaryDLL code</summary rust-toolchain </p</details
Ok, I've submitted a fix. See the PR linked above. is tricky because of the loader lock and other tricks the OS does while a dll is loading.
I know is tricky, but is there any better option to do initialization, if I do not control the exe? And I need to fix the exe (by doing memory patches) before it reaches its .
Possibly not, which is why I filed a fix. Using the std in only works on a "best effort" basis. We do try to support it as much as reasonably possible but there are always going to be limitations due to the OS.
I get maybe a bit crazy idea, but my DLL hooks functions anyway, so if I would limit to and before the hooked main do my initialization. (for my use case any time before main is good enough) Would that eliminate wast majority of potential breaks related to ? Or is it not worth it?
Calling load_library in is susceptible to deadlocks unless the library is already loaded. I think you might just need to be very careful about the dependencies you use. Maybe there's a different or lighter weight logger you can use in place of log4js that doesn't use HashSet?
On further inspection it seems unlikely that fixes the issue although I still think it's a good cleanup and simplification (so I stand by my r+). That is, looking at your back trace... the deadlock you're hitting is from inside BCryptGenRandom itself, not from our code that synchronizes while calling it. It looks like BCryptGenRandom does some synchronizing when getting the preferred RNG (I guess). My hunch is for whatever reason this ends up needing to take the loader lock, and because the loader lock is already held inside , this causes a deadlock. If this is the case, I don't think there's a way for us to solve it... we can't detect it this in advance, nor is there a good alternative approach we can take that doesn't make things worse when outside (and/or on newer systems, which apparently works?). So I'm not sure what we can do about this.