This is an archive of the discontinued LLVM Phabricator instance.

[Windows] Fix UnmapOrDie and MmapAlignedOrDie
ClosedPublic

Authored by rnk on Feb 18 2016, 5:53 PM.

Details

Summary

Now ASan can return virtual memory to the underlying OS. Portable
sanitizer runtime code needs to be aware that UnmapOrDie cannot unmap
part of previous mapping.

In particular, this required changing how we implement MmapAlignedOrDie
on Windows, which is what Allocator32 uses.

The new code first attempts to allocate memory of the given size, and if
it is appropriately aligned, returns early. If not, it frees the memory
and attempts to reserve size + alignment bytes. In this region there
must be an aligned address. We then free the oversized mapping and
request a new mapping at the aligned address immediately after. However,
a thread could allocate that virtual address in between our free and
allocation, so we have to retry if that allocation fails. The existing
thread creation stress test managed to trigger this condition, so the
code isn't totally untested.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk updated this revision to Diff 48442.Feb 18 2016, 5:53 PM
rnk retitled this revision from to [Windows] Fix UnmapOrDie and MmapAlignedOrDie.
rnk updated this object.
rnk added reviewers: kcc, samsonov.
rnk added a subscriber: llvm-commits.
samsonov accepted this revision.Feb 22 2016, 11:28 AM
samsonov edited edge metadata.

Looks reasonable (yet sad).

lib/sanitizer_common/sanitizer_win.cc
141 ↗(On Diff #48442)

Consider

const int kMaxRetries = 10;
for (int retries = 0; retries < kMaxRetries && (mapped_addr == 0 || !IsAligned(mapped_addr, alignment); retries++) { ... }
if (retries == kMaxRetries)
  ReportMmapFailureAndDie(size, mem_type, "allocate aligned", "too many retries");
return (void*)mapped_addr;
This revision is now accepted and ready to land.Feb 22 2016, 11:28 AM
This revision was automatically updated to reflect the committed changes.