Skip to content

Surprising allocation in windows/compat.rs is a footgun for custom allocators #79118

Closed

Description

This function is the problem:

pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
let mut module: Vec<u16> = module.encode_utf16().collect();
module.push(0);
let symbol = CString::new(symbol).unwrap();
unsafe {
let handle = c::GetModuleHandleW(module.as_ptr());
match c::GetProcAddress(handle, symbol.as_ptr()) as usize {
0 => None,
n => Some(n),
}
}
}

AcquireSRWLockExclusive is one of the functions utilizing this compatibility layer. However, most custom allocators indirectly rely on this function.

This means that allocators must be re-entrant, which is essentially impossible since re-entrancy detection requires thread-local storage, which in turn calls AcquireSRWLockExclusive.

For some reason I haven't been able to fathom, this does not always result in a crash, so many custom allocators which rely on TLS appear to work. However, seemingly inconsequential changes (such as changing the size of a struct) result in the program crashing with an access violation or stack overflow.

The fix is to remove this allocation and encode these strings at compile-time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-allocatorsArea: Custom and system allocatorsO-windowsOperating system: WindowsT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions