diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-06-14 01:11:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-14 01:11:09 +0200 |
commit | a3676dd03e21501c7565c8b402a21d4f5a1428c6 (patch) | |
tree | 11fe0e12b22bd11208171a5db9205290fe9c81a2 /src/pal/src/map | |
parent | d0e2f7ebec30be026153fac8f14999e92b196df0 (diff) | |
download | coreclr-a3676dd03e21501c7565c8b402a21d4f5a1428c6.tar.gz coreclr-a3676dd03e21501c7565c8b402a21d4f5a1428c6.tar.bz2 coreclr-a3676dd03e21501c7565c8b402a21d4f5a1428c6.zip |
Fix PAL executable allocator locking (#5770)
We call the ExecutableAllocator from two places in PAL. One is the
VirtualAlloc when the allocation type contains MEM_RESERVE_EXECUTABLE.
The other is MAPMapPEFile.
While the former is called inside of the virtual_critsec critical section,
the latter doesn't take that critical section and so in some race cases,
we were returning the same address twice - once for VirtualAlloc and
once for MAPMapPEFile. That resulted in strange memory corruption cases.
The fix is to use the same critical section for the MAPMapPEFile too.
I am also reverting the change in the virtual commit that was made when
we have thought that the culprit might be in the mprotect.
Diffstat (limited to 'src/pal/src/map')
-rw-r--r-- | src/pal/src/map/map.cpp | 2 | ||||
-rw-r--r-- | src/pal/src/map/virtual.cpp | 18 |
2 files changed, 7 insertions, 13 deletions
diff --git a/src/pal/src/map/map.cpp b/src/pal/src/map/map.cpp index 3700a27eee..cab9c6cbfa 100644 --- a/src/pal/src/map/map.cpp +++ b/src/pal/src/map/map.cpp @@ -2445,7 +2445,7 @@ void * MAPMapPEFile(HANDLE hFile) // First try to reserve virtual memory using ExecutableAllcator. This allows all PE images to be // near each other and close to the coreclr library which also allows the runtime to generate // more efficient code (by avoiding usage of jump stubs). - loadedBase = ReserveMemoryFromExecutableAllocator(virtualSize); + loadedBase = ReserveMemoryFromExecutableAllocator(pThread, virtualSize); if (loadedBase == NULL) { // MAC64 requires we pass MAP_SHARED (or MAP_PRIVATE) flags - otherwise, the call is failed. diff --git a/src/pal/src/map/virtual.cpp b/src/pal/src/map/virtual.cpp index 0d7310c9e3..50d43cf03f 100644 --- a/src/pal/src/map/virtual.cpp +++ b/src/pal/src/map/virtual.cpp @@ -1114,17 +1114,7 @@ static LPVOID VIRTUALCommitMemory( if (allocationType != MEM_COMMIT) { // Commit the pages - void * pRet = MAP_FAILED; -#ifndef __APPLE__ if (mprotect((void *) StartBoundary, MemSize, PROT_WRITE | PROT_READ) == 0) - pRet = (void *)StartBoundary; -#else // __APPLE__ - // Using mprotect above on MacOS is suspect to cause intermittent crashes - // https://github.com/dotnet/coreclr/issues/5672 - pRet = mmap((void *) StartBoundary, MemSize, PROT_WRITE | PROT_READ, - MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0); -#endif // __APPLE__ - if (pRet != MAP_FAILED) { #if MMAP_DOESNOT_ALLOW_REMAP SIZE_T i; @@ -1934,9 +1924,13 @@ Function : that is located close to the coreclr library. The memory comes from the virtual address range that is managed by ExecutableMemoryAllocator. --*/ -void* ReserveMemoryFromExecutableAllocator(SIZE_T allocationSize) +void* ReserveMemoryFromExecutableAllocator(CPalThread* pThread, SIZE_T allocationSize) { - return g_executableMemoryAllocator.AllocateMemory(allocationSize); + InternalEnterCriticalSection(pThread, &virtual_critsec); + void* mem = g_executableMemoryAllocator.AllocateMemory(allocationSize); + InternalLeaveCriticalSection(pThread, &virtual_critsec); + + return mem; } /*++ |