Skip to content

Windows allocator is incompatible with passing heap allocations across DLL libraries with static std #131468

Description

Given two DLLs that contain statically-linked Rust code:

  • One DLL calls Rust to allocate a heap pointer
  • It passes the pointer to the second DLL
  • The second DLL calls Rust to free the heap pointer

The Windows allocation code will crash due to the HEAP global variable being null in the second DLL:

// SAFETY: because `ptr` has been successfully allocated with this allocator,
// `HEAP` must have been successfully initialized.
let heap = unsafe { get_process_heap() };

The allocator code assumes that the allocation already happened in the same DLL.

On other build targets, this setup works fine.

it's not clear why the Rust stdlib goes to all the trouble with the HEAP global variable in the first place. It could just call GetProcessHeap() on each call to HeapAlloc() and HeapFree(). Could we get rid of the HEAP variable?

How did I run into this? You might wonder.

This build setup probably looks weird, but it is a fundamental (bad) thing that Chromium uses for debug developer builds, which we call our component build. We mark subsets of the build graph as components and then everything inside the component is static-linked as usual, but the components are a cluster of DLLs. This breaks global variables and is generally problematic, you might think, and you're right. But it's also deemed to be important for making linking times on Windows debug builds reasonable.

Chromium bug: https://crbug.com/372425130

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

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-windowsOperating system: WindowsT-libsRelevant to the library team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions