-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ICE for wcslen on Windows #3692
Comments
Doing a bit more digging Line 1049 in cc9699d
/// Read a sequence of wchar_t until the first null terminator.
/// Always returns a `Vec<u32>` no matter the size of `wchar_t`.
fn read_wchar_t_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec<u32>> {
let this = self.eval_context_ref();
let wchar_t = this.libc_ty_layout("wchar_t");
self.read_c_str_with_char_size(ptr, wchar_t.size, wchar_t.align.abi)
} If it's pulling type layouts from Rust's libc implementation (which seems to make sense, but there's a lot of indirection going on here and I'm not a Rust compiler guru), then I'm really not sure why it doesn't work, because wchar_t should be u16 for windows msvc: |
PWCSTR from windows-core is explicitly utf-16 / u16. So I further simplified the repro. THis works fine on #[cfg(test)]
mod tests
{
#[cfg(target_os = "windows")]
type NativeWchar = u16;
// This is a hack, but is useful for this repro
#[cfg(not(target_os = "windows"))]
type NativeWchar = u32;
#[test]
pub fn cause_ice()
{
// This isn't the most portable from endianness perspective. But it'll do.
let my_str: [NativeWchar; 2] = ['a' as NativeWchar , 0];
let _len = {
extern "C" {
fn wcslen(s: *const NativeWchar) -> usize;
}
// SAFETY: doesn't matter if it's safe, point is that this triggers an ICE.
let _my_ice_trigger = unsafe { wcslen(my_str.as_ptr()) };
};
}
} To add to the mystery, both x86_64-pc-windows-gnullvm and x86_64-pc-windows-gnu both seem to be fine. and I believe gnullvm is using ucrt. So maybe it's related to just the tools, not even the c library in use? I'm not sure what to make of this. Edit: cargo miri test --target aarch64-pc-windows-msvc and cargo miri test --target arm64ec-pc-windows-msvc also ICE |
Could you provide the error message? Also please see Creating and highlighting code blocks for how to format code blocks so they're more readable. |
Whoops, sorry about the formatting... fixed.
Let me know if there's other information that would help. |
Ah, you posted the ICE file earlier but I overlooked it. So the important part is that miri can't find |
Can't blame you for missing it given my crummy formatting 😄. If it's not related to the libc crate (keeping in mind I'm not familiar with that history), the other theory that comes to mind as I think on it is msvc and msvc library conformance RE: wchar_t. Once upon a time I believe the default was that it just was a typedef, and it's still possible to opt into the non-conformant behavior I believe. Keeping in mind I'm not clear on whether Miri is relying on Rust type metadata (From libc crate?) or debug info or RTTI info or what. Also keeping in mind I have no idea if it's relevant or not, but thought it was worth mentioning in case it is. Maybe the lookup needs to be for __wchar_t? |
Miri relies on the Rust types declared in the
Yes. Our tests call wcslen via We should probably add an assertion to |
FWIW @RalfJung - I did try adding libc as a crate dependency locally after Chris suggested that that might be the issue. It didn't seem to resolve the issue. But I'm guessing that adding libc as a crate dependency for my test crate wouldn't be expected to do it, , as that wouldn't make Miri magically depend on libc/load libc. Thanks for the fast turnaround on the fix, and for all the awesome work you guys have done on Miri! |
Hm, adding it as a dependency should have helped; that's how the test was passing on CI even when it was ICEing for you... maybe you have to also add |
don't rely on libc existing on Windows Fixes rust-lang/miri#3692
Good day folks,
I hit a ICE today. I installed nightly today (and it's reporting 1.81) so I think it's up to date.
This might be related to #2904, but it's not a no_std crate. I see a shim for wcslen in https://github.com/rust-lang/miri/blob/dc286ac1432932b2a710789de40ae8bc4e7ea7c1/src/shims/foreign_items.rs - but it looks like that shim doesn't work for msvc windows targets at a minimum.
But I'm not an expert on Miri.
windows_core::PCWSTR and windows_core::PWSTR both trivially trigger in via their .len() method - meaning a lot of windows code could benefit.
Edit: repro has been minimized further, see #3692 (comment)
It also triggers on PWSTR. I don't think it repros on strlen though - which makes sense with the backtrace.
wcslen is utf16, not utf32, on Windows.
rustc-ice-2024-06-21T01_12_48-101996.txt
The text was updated successfully, but these errors were encountered: